refactor: add organizations system

This commit is contained in:
Mauricio Siu
2025-02-09 20:53:06 -06:00
parent fafc238e70
commit 8bd72a8a34
47 changed files with 359 additions and 171 deletions

View File

@@ -21,6 +21,7 @@ import {
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { authClient } from "@/lib/auth";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon, SquarePen } from "lucide-react";
@@ -97,6 +98,18 @@ export const HandleProject = ({ projectId }: Props) => {
);
});
};
// useEffect(() => {
// const getUsers = async () => {
// const users = await authClient.admin.listUsers({
// query: {
// limit: 100,
// },
// });
// console.log(users);
// };
// getUsers();
// });
return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
@@ -110,10 +123,26 @@ export const HandleProject = ({ projectId }: Props) => {
<span>Update</span>
</DropdownMenuItem>
) : (
<Button>
<PlusIcon className="h-4 w-4" />
Create Project
</Button>
<>
<Button>
<PlusIcon className="h-4 w-4" />
Create Project
</Button>
<Button
onClick={async () => {
const newUser = await authClient.admin.createUser({
name: "Test User",
email: "test4@example.com",
password: "password123",
role: "user",
});
console.log(newUser);
}}
>
Create user
</Button>
</>
)}
</DialogTrigger>
<DialogContent className="sm:m:max-w-lg ">

View File

@@ -57,7 +57,7 @@ export const ShowProjects = () => {
authId: auth?.id || "",
},
{
enabled: !!auth?.id && auth?.rol === "user",
enabled: !!auth?.id && auth?.role === "user",
},
);
const { mutateAsync } = api.project.remove.useMutation();
@@ -91,7 +91,7 @@ export const ShowProjects = () => {
</CardDescription>
</CardHeader>
{(auth?.rol === "admin" || user?.canCreateProjects) && (
{(auth?.role === "admin" || user?.canCreateProjects) && (
<div className="">
<HandleProject />
</div>
@@ -293,7 +293,7 @@ export const ShowProjects = () => {
<div
onClick={(e) => e.stopPropagation()}
>
{(auth?.rol === "admin" ||
{(auth?.role === "admin" ||
user?.canDeleteProjects) && (
<AlertDialog>
<AlertDialogTrigger className="w-full">

View File

@@ -28,6 +28,7 @@ import { BookIcon, CircuitBoard, GlobeIcon } from "lucide-react";
import { useRouter } from "next/router";
import React from "react";
import { StatusTooltip } from "../shared/status-tooltip";
import { authClient } from "@/lib/auth";
type Project = Awaited<ReturnType<typeof findProjectById>>;
@@ -35,8 +36,10 @@ export const SearchCommand = () => {
const router = useRouter();
const [open, setOpen] = React.useState(false);
const [search, setSearch] = React.useState("");
const { data } = api.project.all.useQuery();
const { data: session } = authClient.getSession();
const { data } = api.project.all.useQuery(undefined, {
enabled: !!session,
});
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
React.useEffect(() => {

View File

@@ -155,7 +155,7 @@ const MENU: Menu = {
// Only enabled for admins and users with access to Traefik files in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!(
(auth?.rol === "admin" || user?.canAccessToTraefikFiles) &&
(auth?.role === "admin" || user?.canAccessToTraefikFiles) &&
!isCloud
),
},
@@ -166,7 +166,7 @@ const MENU: Menu = {
icon: BlocksIcon,
// Only enabled for admins and users with access to Docker in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
!!((auth?.role === "admin" || user?.canAccessToDocker) && !isCloud),
},
{
isSingle: true,
@@ -175,7 +175,7 @@ const MENU: Menu = {
icon: PieChart,
// Only enabled for admins and users with access to Docker in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
!!((auth?.role === "admin" || user?.canAccessToDocker) && !isCloud),
},
{
isSingle: true,
@@ -184,7 +184,7 @@ const MENU: Menu = {
icon: Forward,
// Only enabled for admins and users with access to Docker in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!((auth?.rol === "admin" || user?.canAccessToDocker) && !isCloud),
!!((auth?.role === "admin" || user?.canAccessToDocker) && !isCloud),
},
// Legacy unused menu, adjusted to the new structure
@@ -252,7 +252,7 @@ const MENU: Menu = {
icon: Activity,
// Only enabled for admins in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!(auth?.rol === "admin" && !isCloud),
!!(auth?.role === "admin" && !isCloud),
},
{
isSingle: true,
@@ -266,7 +266,7 @@ const MENU: Menu = {
url: "/dashboard/settings/servers",
icon: Server,
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
isSingle: true,
@@ -274,7 +274,7 @@ const MENU: Menu = {
icon: Users,
url: "/dashboard/settings/users",
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
isSingle: true,
@@ -283,7 +283,7 @@ const MENU: Menu = {
url: "/dashboard/settings/ssh-keys",
// Only enabled for admins and users with access to SSH keys
isEnabled: ({ auth, user }) =>
!!(auth?.rol === "admin" || user?.canAccessToSSHKeys),
!!(auth?.role === "admin" || user?.canAccessToSSHKeys),
},
{
isSingle: true,
@@ -292,7 +292,7 @@ const MENU: Menu = {
icon: GitBranch,
// Only enabled for admins and users with access to Git providers
isEnabled: ({ auth, user }) =>
!!(auth?.rol === "admin" || user?.canAccessToGitProviders),
!!(auth?.role === "admin" || user?.canAccessToGitProviders),
},
{
isSingle: true,
@@ -300,7 +300,7 @@ const MENU: Menu = {
url: "/dashboard/settings/registry",
icon: Package,
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
isSingle: true,
@@ -308,7 +308,7 @@ const MENU: Menu = {
url: "/dashboard/settings/destinations",
icon: Database,
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
@@ -317,7 +317,7 @@ const MENU: Menu = {
url: "/dashboard/settings/certificates",
icon: ShieldCheck,
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
isSingle: true,
@@ -326,7 +326,7 @@ const MENU: Menu = {
icon: Boxes,
// Only enabled for admins in non-cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!(auth?.rol === "admin" && !isCloud),
!!(auth?.role === "admin" && !isCloud),
},
{
isSingle: true,
@@ -334,7 +334,7 @@ const MENU: Menu = {
url: "/dashboard/settings/notifications",
icon: Bell,
// Only enabled for admins
isEnabled: ({ auth, user, isCloud }) => !!(auth?.rol === "admin"),
isEnabled: ({ auth, user, isCloud }) => !!(auth?.role === "admin"),
},
{
isSingle: true,
@@ -343,7 +343,7 @@ const MENU: Menu = {
icon: CreditCard,
// Only enabled for admins in cloud environments
isEnabled: ({ auth, user, isCloud }) =>
!!(auth?.rol === "admin" && isCloud),
!!(auth?.role === "admin" && isCloud),
},
],
@@ -537,7 +537,7 @@ export default function Page({ children }: Props) {
authId: auth?.id || "",
},
{
enabled: !!auth?.id && auth?.rol === "user",
enabled: !!auth?.id && auth?.role === "user",
},
);
@@ -783,7 +783,7 @@ export default function Page({ children }: Props) {
</SidebarMenuButton>
</SidebarMenuItem>
))}
{!isCloud && auth?.rol === "admin" && (
{!isCloud && auth?.role === "admin" && (
<SidebarMenuItem>
<SidebarMenuButton asChild>
<UpdateServerButton />

View File

@@ -24,6 +24,7 @@ import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";
import { ModeToggle } from "../ui/modeToggle";
import { SidebarMenuButton } from "../ui/sidebar";
import { authClient } from "@/lib/auth";
const AUTO_CHECK_UPDATES_INTERVAL_MINUTES = 7;
@@ -40,7 +41,7 @@ export const UserNav = () => {
},
);
const { locale, setLocale } = useLocale();
const { mutateAsync } = api.auth.logout.useMutation();
// const { mutateAsync } = api.auth.logout.useMutation();
return (
<DropdownMenu>
@@ -178,9 +179,12 @@ export const UserNav = () => {
<DropdownMenuItem
className="cursor-pointer"
onClick={async () => {
await mutateAsync().then(() => {
await authClient.signOut().then(() => {
router.push("/");
});
// await mutateAsync().then(() => {
// router.push("/");
// });
}}
>
Log out