diff --git a/package-lock.json b/package-lock.json
index 0446cb3a..a985311d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"@headlessui/react": "^2.2.0",
"@hookform/resolvers": "^5.0.1",
"@inertiajs/react": "^2.0.0",
+ "@radix-ui/react-alert-dialog": "^1.1.13",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-collapsible": "^1.1.3",
@@ -1201,6 +1202,34 @@
"integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
"license": "MIT"
},
+ "node_modules/@radix-ui/react-alert-dialog": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.13.tgz",
+ "integrity": "sha512-/uPs78OwxGxslYOG5TKeUsv9fZC0vo376cXSADdKirTmsLJU2au6L3n34c3p6W26rFDDDze/hwy4fYeNd0qdGA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dialog": "1.1.13",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-slot": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
"node_modules/@radix-ui/react-arrow": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.6.tgz",
diff --git a/package.json b/package.json
index b9d68914..601c3b67 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"@headlessui/react": "^2.2.0",
"@hookform/resolvers": "^5.0.1",
"@inertiajs/react": "^2.0.0",
+ "@radix-ui/react-alert-dialog": "^1.1.13",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-collapsible": "^1.1.3",
diff --git a/resources/js/components/app-command.tsx b/resources/js/components/app-command.tsx
new file mode 100644
index 00000000..2acf1b76
--- /dev/null
+++ b/resources/js/components/app-command.tsx
@@ -0,0 +1,43 @@
+import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/components/ui/command';
+import { useEffect, useState } from 'react';
+import { Button } from '@/components/ui/button';
+import { CommandIcon, SearchIcon } from 'lucide-react';
+
+export default function AppCommand() {
+ const [open, setOpen] = useState(false);
+
+ useEffect(() => {
+ const down = (e: KeyboardEvent) => {
+ if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
+ e.preventDefault();
+ setOpen((open) => !open);
+ }
+ };
+
+ document.addEventListener('keydown', down);
+ return () => document.removeEventListener('keydown', down);
+ }, []);
+
+ return (
+
+
+
+
+
+ No results found.
+
+ Create server
+ Create project
+
+
+
+
+ );
+}
diff --git a/resources/js/components/app-header.tsx b/resources/js/components/app-header.tsx
index d4b3b601..f32a1ba8 100644
--- a/resources/js/components/app-header.tsx
+++ b/resources/js/components/app-header.tsx
@@ -3,24 +3,28 @@ import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator } from
import { ProjectSwitch } from '@/components/project-switch';
import { SlashIcon } from 'lucide-react';
import { ServerSwitch } from '@/components/server-switch';
+import AppCommand from '@/components/app-command';
export function AppHeader() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/resources/js/components/ui/alert-dialog.tsx b/resources/js/components/ui/alert-dialog.tsx
new file mode 100644
index 00000000..935eecf3
--- /dev/null
+++ b/resources/js/components/ui/alert-dialog.tsx
@@ -0,0 +1,155 @@
+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) {
+ return
+}
+
+function AlertDialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogContent({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+ )
+}
+
+function AlertDialogHeader({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDialogFooter({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogAction({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogCancel({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ AlertDialog,
+ AlertDialogPortal,
+ AlertDialogOverlay,
+ AlertDialogTrigger,
+ AlertDialogContent,
+ AlertDialogHeader,
+ AlertDialogFooter,
+ AlertDialogTitle,
+ AlertDialogDescription,
+ AlertDialogAction,
+ AlertDialogCancel,
+}
diff --git a/resources/js/pages/projects/components/users-action.tsx b/resources/js/pages/projects/components/users-action.tsx
index 913074dd..bf524d93 100644
--- a/resources/js/pages/projects/components/users-action.tsx
+++ b/resources/js/pages/projects/components/users-action.tsx
@@ -20,6 +20,17 @@ import InputError from '@/components/ui/input-error';
import UserSelect from '@/components/user-select';
import { useForm } from '@inertiajs/react';
import { LoaderCircleIcon, TrashIcon } from 'lucide-react';
+import {
+ AlertDialog,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+ AlertDialogCancel,
+ AlertDialogAction,
+} from '@/components/ui/alert-dialog';
function AddUser({ project }: { project: Project }) {
const [open, setOpen] = useState(false);
@@ -84,30 +95,27 @@ function RemoveUser({ project, user }: { project: Project; user: User }) {
};
return (
-
+
+
+
);
}