mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: improve UI
This commit is contained in:
@@ -25,8 +25,8 @@ export const DeleteApplication = ({ applicationId }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ export const DeleteDomain = ({ domainId }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ export const ShowDomains = ({ applicationId }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{data && data?.length > 0 && (
|
{data && data?.length > 0 && (
|
||||||
<AddDomain applicationId={applicationId} />
|
<AddDomain applicationId={applicationId}>
|
||||||
|
<GlobeIcon className="size-4" /> Add Domain
|
||||||
|
</AddDomain>
|
||||||
)}
|
)}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex w-full flex-row gap-4">
|
<CardContent className="flex w-full flex-row gap-4">
|
||||||
@@ -51,7 +53,9 @@ export const ShowDomains = ({ applicationId }: Props) => {
|
|||||||
To access to the application is required to set at least 1
|
To access to the application is required to set at least 1
|
||||||
domain
|
domain
|
||||||
</span>
|
</span>
|
||||||
<AddDomain applicationId={applicationId}>Add Domain</AddDomain>
|
<AddDomain applicationId={applicationId}>
|
||||||
|
<GlobeIcon className="size-4" /> Add Domain
|
||||||
|
</AddDomain>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex w-full flex-col gap-4">
|
<div className="flex w-full flex-col gap-4">
|
||||||
@@ -75,8 +79,10 @@ export const ShowDomains = ({ applicationId }: Props) => {
|
|||||||
<Button variant="outline" disabled>
|
<Button variant="outline" disabled>
|
||||||
{item.https ? "HTTPS" : "HTTP"}
|
{item.https ? "HTTPS" : "HTTP"}
|
||||||
</Button>
|
</Button>
|
||||||
<UpdateDomain domainId={item.domainId} />
|
<div className="flex flex-row gap-1">
|
||||||
<DeleteDomain domainId={item.domainId} />
|
<UpdateDomain domainId={item.domainId} />
|
||||||
|
<DeleteDomain domainId={item.domainId} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ export const UpdateDomain = ({ domainId }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger className="" asChild>
|
<DialogTrigger className="" asChild>
|
||||||
<Button>
|
<Button variant="ghost">
|
||||||
<PenBoxIcon className="size-4" />
|
<PenBoxIcon className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-2xl">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-2xl">
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdateApplication = ({ applicationId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
AlertDialogContent,
|
AlertDialogContent,
|
||||||
AlertDialogDescription,
|
AlertDialogDescription,
|
||||||
AlertDialogFooter,
|
AlertDialogFooter,
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
@@ -16,47 +16,47 @@ import { useRouter } from "next/router";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mariadbId: string;
|
mariadbId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteMariadb = ({ mariadbId }: Props) => {
|
export const DeleteMariadb = ({ mariadbId }: Props) => {
|
||||||
const { mutateAsync, isLoading } = api.mariadb.remove.useMutation();
|
const { mutateAsync, isLoading } = api.mariadb.remove.useMutation();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This will permanently delete the
|
This action cannot be undone. This will permanently delete the
|
||||||
database
|
database
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
mariadbId,
|
mariadbId,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
push(`/dashboard/project/${data?.projectId}`);
|
push(`/dashboard/project/${data?.projectId}`);
|
||||||
toast.success("Database delete succesfully");
|
toast.success("Database delete succesfully");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete the database");
|
toast.error("Error to delete the database");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdateMariadb = ({ mariadbId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
AlertDialogContent,
|
AlertDialogContent,
|
||||||
AlertDialogDescription,
|
AlertDialogDescription,
|
||||||
AlertDialogFooter,
|
AlertDialogFooter,
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
@@ -16,47 +16,47 @@ import { useRouter } from "next/router";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mongoId: string;
|
mongoId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteMongo = ({ mongoId }: Props) => {
|
export const DeleteMongo = ({ mongoId }: Props) => {
|
||||||
const { mutateAsync, isLoading } = api.mongo.remove.useMutation();
|
const { mutateAsync, isLoading } = api.mongo.remove.useMutation();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This will permanently delete the
|
This action cannot be undone. This will permanently delete the
|
||||||
database
|
database
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
mongoId,
|
mongoId,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
push(`/dashboard/project/${data?.projectId}`);
|
push(`/dashboard/project/${data?.projectId}`);
|
||||||
toast.success("Database delete succesfully");
|
toast.success("Database delete succesfully");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete the database");
|
toast.error("Error to delete the database");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdateMongo = ({ mongoId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
AlertDialogContent,
|
AlertDialogContent,
|
||||||
AlertDialogDescription,
|
AlertDialogDescription,
|
||||||
AlertDialogFooter,
|
AlertDialogFooter,
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
@@ -16,47 +16,47 @@ import { useRouter } from "next/router";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mysqlId: string;
|
mysqlId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteMysql = ({ mysqlId }: Props) => {
|
export const DeleteMysql = ({ mysqlId }: Props) => {
|
||||||
const { mutateAsync, isLoading } = api.mysql.remove.useMutation();
|
const { mutateAsync, isLoading } = api.mysql.remove.useMutation();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This will permanently delete the
|
This action cannot be undone. This will permanently delete the
|
||||||
database
|
database
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
mysqlId,
|
mysqlId,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
push(`/dashboard/project/${data?.projectId}`);
|
push(`/dashboard/project/${data?.projectId}`);
|
||||||
toast.success("Database delete succesfully");
|
toast.success("Database delete succesfully");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete the database");
|
toast.error("Error to delete the database");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdateMysql = ({ mysqlId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
AlertDialogContent,
|
AlertDialogContent,
|
||||||
AlertDialogDescription,
|
AlertDialogDescription,
|
||||||
AlertDialogFooter,
|
AlertDialogFooter,
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
@@ -16,47 +16,47 @@ import { useRouter } from "next/router";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
postgresId: string;
|
postgresId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeletePostgres = ({ postgresId }: Props) => {
|
export const DeletePostgres = ({ postgresId }: Props) => {
|
||||||
const { mutateAsync, isLoading } = api.postgres.remove.useMutation();
|
const { mutateAsync, isLoading } = api.postgres.remove.useMutation();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This will permanently delete the
|
This action cannot be undone. This will permanently delete the
|
||||||
database
|
database
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
postgresId,
|
postgresId,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
push(`/dashboard/project/${data?.projectId}`);
|
push(`/dashboard/project/${data?.projectId}`);
|
||||||
toast.success("Database delete succesfully");
|
toast.success("Database delete succesfully");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete the database");
|
toast.error("Error to delete the database");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdatePostgres = ({ postgresId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
AlertDialogContent,
|
AlertDialogContent,
|
||||||
AlertDialogDescription,
|
AlertDialogDescription,
|
||||||
AlertDialogFooter,
|
AlertDialogFooter,
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
@@ -16,47 +16,47 @@ import { useRouter } from "next/router";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
redisId: string;
|
redisId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteRedis = ({ redisId }: Props) => {
|
export const DeleteRedis = ({ redisId }: Props) => {
|
||||||
const { mutateAsync, isLoading } = api.redis.remove.useMutation();
|
const { mutateAsync, isLoading } = api.redis.remove.useMutation();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive" isLoading={isLoading}>
|
<Button variant="ghost" isLoading={isLoading}>
|
||||||
<TrashIcon className="size-4 " />
|
<TrashIcon className="size-4 text-muted-foreground " />
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This will permanently delete the
|
This action cannot be undone. This will permanently delete the
|
||||||
database
|
database
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
redisId,
|
redisId,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
push(`/dashboard/project/${data?.projectId}`);
|
push(`/dashboard/project/${data?.projectId}`);
|
||||||
toast.success("Database delete succesfully");
|
toast.success("Database delete succesfully");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete the database");
|
toast.error("Error to delete the database");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const UpdateRedis = ({ redisId }: Props) => {
|
|||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="ghost">
|
<Button variant="ghost">
|
||||||
<SquarePen className="size-4" />
|
<SquarePen className="size-4 text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||||
|
|||||||
@@ -33,21 +33,23 @@ export const ShowCertificates = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
{data?.map((destination, index) => (
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
||||||
<div
|
{data?.map((destination, index) => (
|
||||||
key={destination.certificateId}
|
<div
|
||||||
className="flex items-center justify-between"
|
key={destination.certificateId}
|
||||||
>
|
className="flex items-center justify-between border p-4 rounded-lg"
|
||||||
<span className="text-sm text-muted-foreground">
|
>
|
||||||
{index + 1}. {destination.name}
|
<span className="text-sm text-muted-foreground">
|
||||||
</span>
|
{index + 1}. {destination.name}
|
||||||
<div className="flex flex-row gap-3">
|
</span>
|
||||||
<DeleteCertificate
|
<div className="flex flex-row gap-3">
|
||||||
certificateId={destination.certificateId}
|
<DeleteCertificate
|
||||||
/>
|
certificateId={destination.certificateId}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<AddCertificate />
|
<AddCertificate />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ export const AddNode = () => {
|
|||||||
<DialogTitle>Add Node</DialogTitle>
|
<DialogTitle>Add Node</DialogTitle>
|
||||||
<DialogDescription className="flex flex-col gap-2">
|
<DialogDescription className="flex flex-col gap-2">
|
||||||
Follow the steps to add a new node to your cluster, before you start
|
Follow the steps to add a new node to your cluster, before you start
|
||||||
working with this feature, you need to understand how docker swarm
|
using this feature, you need to understand how docker swarm works.{" "}
|
||||||
works.{" "}
|
|
||||||
<Link
|
<Link
|
||||||
href="https://docs.docker.com/engine/swarm/"
|
href="https://docs.docker.com/engine/swarm/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
@@ -52,16 +52,16 @@ export const ShowRegistry = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-6">
|
||||||
{data?.map((registry, index) => (
|
{data?.map((registry, index) => (
|
||||||
<div
|
<div
|
||||||
key={registry.registryId}
|
key={registry.registryId}
|
||||||
className="flex items-center justify-between border p-4 rounded-lg hover:bg-muted cursor-pointer"
|
className="flex items-center justify-between border p-4 rounded-lg"
|
||||||
>
|
>
|
||||||
<span className="text-sm text-muted-foreground">
|
<span className="text-sm text-muted-foreground">
|
||||||
{index + 1}. {registry.registryName}
|
{index + 1}. {registry.registryName}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-row gap-3">
|
<div className="flex flex-row gap-1">
|
||||||
<UpdateDockerRegistry registryId={registry.registryId} />
|
<UpdateDockerRegistry registryId={registry.registryId} />
|
||||||
<DeleteRegistry registryId={registry.registryId} />
|
<DeleteRegistry registryId={registry.registryId} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,16 +34,16 @@ export const ShowDestinations = () => {
|
|||||||
<AddDestination />
|
<AddDestination />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-4">
|
||||||
{data?.map((destination, index) => (
|
{data?.map((destination, index) => (
|
||||||
<div
|
<div
|
||||||
key={destination.destinationId}
|
key={destination.destinationId}
|
||||||
className="flex items-center justify-between"
|
className="flex items-center justify-between border p-3.5 rounded-lg"
|
||||||
>
|
>
|
||||||
<span className="text-sm text-muted-foreground">
|
<span className="text-sm text-muted-foreground">
|
||||||
{index + 1}. {destination.name}
|
{index + 1}. {destination.name}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-row gap-3">
|
<div className="flex flex-row gap-1">
|
||||||
<UpdateDestination
|
<UpdateDestination
|
||||||
destinationId={destination.destinationId}
|
destinationId={destination.destinationId}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ export const GithubSetup = () => {
|
|||||||
{haveGithubConfigured ? (
|
{haveGithubConfigured ? (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground text-sm">
|
||||||
Github account configured succesfully.
|
Github account configured succesfully.
|
||||||
</span>
|
</span>
|
||||||
<BadgeCheck className="size-5 text-green-700" />
|
<BadgeCheck className="size-4 text-green-700" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-end">
|
<div className="flex items-end">
|
||||||
<RemoveGithubApp />
|
<RemoveGithubApp />
|
||||||
@@ -101,9 +101,9 @@ export const GithubSetup = () => {
|
|||||||
{data?.githubAppName ? (
|
{data?.githubAppName ? (
|
||||||
<div className="flex w-fit flex-col gap-4">
|
<div className="flex w-fit flex-col gap-4">
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
Youve successfully created a GitHub app named
|
You've successfully created a github app named{" "}
|
||||||
{data.githubAppName}! The next step is to install this app in
|
<strong>{data.githubAppName}</strong>! The next step is to
|
||||||
your GitHub account.
|
install this app in your GitHub account.
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-4">
|
||||||
@@ -121,12 +121,12 @@ export const GithubSetup = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-muted-foreground">
|
<p className="text-muted-foreground text-sm">
|
||||||
To integrate your GitHub account with our services, youll
|
To integrate your GitHub account with our services, you'll
|
||||||
need to create and install a GitHub app. This process is
|
need to create and install a GitHub app. This process is
|
||||||
straightforward and only takes a few minutes. Click the
|
straightforward and only takes a few minutes. Click the
|
||||||
button below to get started.
|
button below to get started.
|
||||||
</span>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4 flex flex-col gap-4">
|
<div className="mt-4 flex flex-col gap-4">
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ import { extractServices } from "@/pages/dashboard/project/[projectId]";
|
|||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { AlertBlock } from "@/components/shared/alert-block";
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { ListTodo } from "lucide-react";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
|
||||||
|
|
||||||
const addPermissions = z.object({
|
const addPermissions = z.object({
|
||||||
accesedProjects: z.array(z.string()).optional(),
|
accesedProjects: z.array(z.string()).optional(),
|
||||||
@@ -107,9 +107,12 @@ export const AddUserPermissions = ({ userId }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger className="" asChild>
|
<DialogTrigger className="" asChild>
|
||||||
<Button variant="ghost">
|
<DropdownMenuItem
|
||||||
<ListTodo className="size-4 text-muted-foreground " />
|
className="w-full cursor-pointer"
|
||||||
</Button>
|
onSelect={(e) => e.preventDefault()}
|
||||||
|
>
|
||||||
|
Add Permissions
|
||||||
|
</DropdownMenuItem>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-4xl">
|
<DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-4xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { useEffect } from "react";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { PlusIcon } from "lucide-react";
|
||||||
|
|
||||||
const addUser = z.object({
|
const addUser = z.object({
|
||||||
email: z
|
email: z
|
||||||
@@ -66,7 +67,9 @@ export const AddUser = () => {
|
|||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger className="" asChild>
|
<DialogTrigger className="" asChild>
|
||||||
<Button>Add User</Button>
|
<Button>
|
||||||
|
<PlusIcon className="h-4 w-4" /> Add User
|
||||||
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-2xl">
|
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-2xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { TrashIcon } from "lucide-react";
|
import { TrashIcon } from "lucide-react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
authId: string;
|
authId: string;
|
||||||
@@ -24,9 +25,12 @@ export const DeleteUser = ({ authId }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="ghost" isLoading={isLoading}>
|
<DropdownMenuItem
|
||||||
<TrashIcon className="size-4 text-muted-foreground " />
|
className="w-full cursor-pointer"
|
||||||
</Button>
|
onSelect={(e) => e.preventDefault()}
|
||||||
|
>
|
||||||
|
Delete User
|
||||||
|
</DropdownMenuItem>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { CopyIcon, Users } from "lucide-react";
|
import { MoreHorizontal, Users } from "lucide-react";
|
||||||
import { AddUser } from "./add-user";
|
import { AddUser } from "./add-user";
|
||||||
import { DeleteUser } from "./delete-user";
|
import { DeleteUser } from "./delete-user";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
@@ -14,7 +14,24 @@ import { useEffect, useState } from "react";
|
|||||||
import { AddUserPermissions } from "./add-permissions";
|
import { AddUserPermissions } from "./add-permissions";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { UpdateUser } from "./update-user";
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCaption,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
export const ShowUsers = () => {
|
export const ShowUsers = () => {
|
||||||
const { data } = api.user.all.useQuery();
|
const { data } = api.user.all.useQuery();
|
||||||
@@ -25,82 +42,109 @@ export const ShowUsers = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full col-span-2">
|
<div className="h-full col-span-2">
|
||||||
<Card className="bg-transparent h-full border-none">
|
<Card className="bg-transparent h-full ">
|
||||||
<CardHeader>
|
<CardHeader className="flex flex-row gap-2 justify-between w-full flex-wrap">
|
||||||
<CardTitle className="text-xl">Users</CardTitle>
|
<div className="flex flex-col gap-2">
|
||||||
<CardDescription>Add, manage and delete users.</CardDescription>
|
<CardTitle className="text-xl">Users</CardTitle>
|
||||||
|
<CardDescription>Add, manage and delete users.</CardDescription>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{data && data.length > 0 && (
|
||||||
|
<div className="flex flex-col gap-3 items-end">
|
||||||
|
<AddUser />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-2 h-full">
|
<CardContent className="space-y-2 h-full">
|
||||||
{data?.length === 0 ? (
|
{data?.length === 0 ? (
|
||||||
<div className="flex flex-col items-center gap-3">
|
<div className="flex flex-col items-center gap-3">
|
||||||
<Users className="size-8 self-center text-muted-foreground" />
|
<Users className="size-8 self-center text-muted-foreground" />
|
||||||
<span className="text-base text-muted-foreground">
|
<span className="text-base text-muted-foreground">
|
||||||
To create a user is required to add
|
To create a user, you need to add:
|
||||||
</span>
|
</span>
|
||||||
<AddUser />
|
<AddUser />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
{data?.map((user) => {
|
<Table>
|
||||||
return (
|
<TableCaption>See all users</TableCaption>
|
||||||
<div
|
<TableHeader>
|
||||||
key={user.userId}
|
<TableRow>
|
||||||
className="flex gap-2 flex-col justify-start border p-4 rounded-lg"
|
<TableHead className="w-[100px]">Email</TableHead>
|
||||||
>
|
<TableHead className="text-center">Status</TableHead>
|
||||||
<span className="text-sm text-foreground">
|
<TableHead className="text-center">2FA</TableHead>
|
||||||
{user.auth.email}
|
<TableHead className="text-center">Expiration</TableHead>
|
||||||
</span>
|
<TableHead className="text-right">Actions</TableHead>
|
||||||
{!user.isRegistered && (
|
</TableRow>
|
||||||
<span className="text-sm text-muted-foreground">
|
</TableHeader>
|
||||||
Expire In{" "}
|
<TableBody>
|
||||||
{format(new Date(user.expirationDate), "PPpp")}
|
{data?.map((user) => {
|
||||||
</span>
|
return (
|
||||||
)}
|
<TableRow key={user.userId}>
|
||||||
|
<TableCell className="w-[100px]">
|
||||||
<span className="text-sm text-muted-foreground">
|
{user.auth.email}
|
||||||
{user.isRegistered ? "Registered" : "Not Registered"}
|
</TableCell>
|
||||||
</span>
|
<TableCell className="text-center">
|
||||||
{user.auth.is2FAEnabled && (
|
<Badge
|
||||||
<span className="text-sm text-muted-foreground">
|
variant={
|
||||||
{user.auth.is2FAEnabled
|
user.isRegistered ? "default" : "secondary"
|
||||||
? "2FA Enabled"
|
}
|
||||||
: "2FA Not Enabled"}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="flex flex-wrap flex-row gap-3">
|
|
||||||
{!user.isRegistered && (
|
|
||||||
<div className="overflow-x-auto flex flex-row gap-4 items-center">
|
|
||||||
<div className="overflow-x-auto">
|
|
||||||
<span className="text-sm text-muted-foreground ">
|
|
||||||
{`${url}/invitation?token=${user.token}`}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
// className="absolute right-2 top-2"
|
|
||||||
onClick={() => {
|
|
||||||
copy(`${url}/invitation?token=${user.token}`);
|
|
||||||
toast.success("Invitation Copied to clipboard");
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<CopyIcon className="size-4 text-muted-foreground" />
|
{user.isRegistered
|
||||||
</button>
|
? "Registered"
|
||||||
</div>
|
: "Not Registered"}
|
||||||
)}
|
</Badge>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center">
|
||||||
|
{user.auth.is2FAEnabled
|
||||||
|
? "2FA Enabled"
|
||||||
|
: "2FA Not Enabled"}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-right">
|
||||||
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{format(new Date(user.expirationDate), "PPpp")}
|
||||||
|
</span>
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
{user.isRegistered && (
|
<TableCell className="text-right flex justify-end">
|
||||||
<AddUserPermissions userId={user.userId} />
|
<DropdownMenu>
|
||||||
)}
|
<DropdownMenuTrigger asChild>
|
||||||
{user.isRegistered && <UpdateUser authId={user.authId} />}
|
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||||
<DeleteUser authId={user.authId} />
|
<span className="sr-only">Open menu</span>
|
||||||
</div>
|
<MoreHorizontal className="h-4 w-4" />
|
||||||
</div>
|
</Button>
|
||||||
);
|
</DropdownMenuTrigger>
|
||||||
})}
|
<DropdownMenuContent align="end">
|
||||||
<div className="flex flex-col justify-end gap-3 w-full items-end">
|
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
||||||
<AddUser />
|
{!user.isRegistered && (
|
||||||
</div>
|
<DropdownMenuItem
|
||||||
|
className="w-full cursor-pointer"
|
||||||
|
onSelect={(e) => {
|
||||||
|
copy(
|
||||||
|
`${origin}/invitation?token=${user.token}`,
|
||||||
|
);
|
||||||
|
toast.success(
|
||||||
|
"Invitation Copied to clipboard",
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Copy Invitation
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{user.isRegistered && (
|
||||||
|
<AddUserPermissions userId={user.userId} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<DeleteUser authId={user.authId} />
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ const Service = (
|
|||||||
<TabsTrigger value="domains">Domains</TabsTrigger>
|
<TabsTrigger value="domains">Domains</TabsTrigger>
|
||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdateApplication applicationId={applicationId} />
|
<UpdateApplication applicationId={applicationId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeleteApplication applicationId={applicationId} />
|
<DeleteApplication applicationId={applicationId} />
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const Mariadb = (
|
|||||||
<TabsTrigger value="logs">Logs</TabsTrigger>
|
<TabsTrigger value="logs">Logs</TabsTrigger>
|
||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdateMariadb mariadbId={mariadbId} />
|
<UpdateMariadb mariadbId={mariadbId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeleteMariadb mariadbId={mariadbId} />
|
<DeleteMariadb mariadbId={mariadbId} />
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ const Mongo = (
|
|||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdateMongo mongoId={mongoId} />
|
<UpdateMongo mongoId={mongoId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeleteMongo mongoId={mongoId} />
|
<DeleteMongo mongoId={mongoId} />
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ const MySql = (
|
|||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdateMysql mysqlId={mysqlId} />
|
<UpdateMysql mysqlId={mysqlId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeleteMysql mysqlId={mysqlId} />
|
<DeleteMysql mysqlId={mysqlId} />
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ const Postgresql = (
|
|||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdatePostgres postgresId={postgresId} />
|
<UpdatePostgres postgresId={postgresId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeletePostgres postgresId={postgresId} />
|
<DeletePostgres postgresId={postgresId} />
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const Redis = (
|
|||||||
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
<TabsTrigger value="advanced">Advanced</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-2">
|
||||||
<UpdateRedis redisId={redisId} />
|
<UpdateRedis redisId={redisId} />
|
||||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||||
<DeleteRedis redisId={redisId} />
|
<DeleteRedis redisId={redisId} />
|
||||||
|
|||||||
Reference in New Issue
Block a user