mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: migrate admin API calls to user router
This commit is contained in:
@@ -39,7 +39,7 @@ export const calculatePrice = (count: number, isAnnual = false) => {
|
||||
};
|
||||
export const ShowBilling = () => {
|
||||
const { data: servers } = api.server.all.useQuery(undefined);
|
||||
const { data: admin } = api.admin.one.useQuery();
|
||||
const { data: admin } = api.user.get.useQuery();
|
||||
const { data, isLoading } = api.stripe.getProducts.useQuery();
|
||||
const { mutateAsync: createCheckoutSession } =
|
||||
api.stripe.createCheckoutSession.useMutation();
|
||||
@@ -70,7 +70,7 @@ export const ShowBilling = () => {
|
||||
return isAnnual ? interval === "year" : interval === "month";
|
||||
});
|
||||
|
||||
const maxServers = admin?.serversQuantity ?? 1;
|
||||
const maxServers = admin?.user.serversQuantity ?? 1;
|
||||
const percentage = ((servers?.length ?? 0) / maxServers) * 100;
|
||||
const safePercentage = Math.min(percentage, 100);
|
||||
|
||||
@@ -98,17 +98,17 @@ export const ShowBilling = () => {
|
||||
<TabsTrigger value="annual">Annual</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
{admin?.stripeSubscriptionId && (
|
||||
{admin?.user.stripeSubscriptionId && (
|
||||
<div className="space-y-2 flex flex-col">
|
||||
<h3 className="text-lg font-medium">Servers Plan</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
You have {servers?.length} server on your plan of{" "}
|
||||
{admin?.serversQuantity} servers
|
||||
{admin?.user.serversQuantity} servers
|
||||
</p>
|
||||
<div>
|
||||
<Progress value={safePercentage} className="max-w-lg" />
|
||||
</div>
|
||||
{admin && admin.serversQuantity! <= servers?.length! && (
|
||||
{admin && admin.user.serversQuantity! <= servers?.length! && (
|
||||
<div className="flex flex-row gap-4 p-2 bg-yellow-50 dark:bg-yellow-950 rounded-lg items-center">
|
||||
<AlertTriangle className="text-yellow-600 dark:text-yellow-400" />
|
||||
<span className="text-sm text-yellow-600 dark:text-yellow-400">
|
||||
@@ -279,7 +279,7 @@ export const ShowBilling = () => {
|
||||
"flex flex-row items-center gap-2 mt-4",
|
||||
)}
|
||||
>
|
||||
{admin?.stripeCustomerId && (
|
||||
{admin?.user.stripeCustomerId && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="w-full"
|
||||
|
||||
@@ -10,7 +10,7 @@ import type React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export const ShowWelcomeDokploy = () => {
|
||||
const { data } = api.auth.get.useQuery();
|
||||
const { data } = api.user.get.useQuery();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||
|
||||
@@ -53,7 +53,7 @@ export const AddBitbucketProvider = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const url = useUrl();
|
||||
const { mutateAsync, error, isError } = api.bitbucket.create.useMutation();
|
||||
const { data: auth } = api.auth.get.useQuery();
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const router = useRouter();
|
||||
const form = useForm<Schema>({
|
||||
defaultValues: {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { useEffect, useState } from "react";
|
||||
export const AddGithubProvider = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const { data: activeOrganization } = authClient.useActiveOrganization();
|
||||
const { data } = api.auth.get.useQuery();
|
||||
const { data } = api.user.get.useQuery();
|
||||
const [manifest, setManifest] = useState("");
|
||||
const [isOrganization, setIsOrganization] = useState(false);
|
||||
const [organizationName, setOrganization] = useState("");
|
||||
|
||||
@@ -55,7 +55,7 @@ export const AddGitlabProvider = () => {
|
||||
const utils = api.useUtils();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const url = useUrl();
|
||||
const { data: auth } = api.auth.get.useQuery();
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { mutateAsync, error, isError } = api.gitlab.create.useMutation();
|
||||
const webhookUrl = `${url}/api/providers/gitlab/callback`;
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export const Disable2FA = () => {
|
||||
|
||||
toast.success("2FA disabled successfully");
|
||||
utils.auth.get.invalidate();
|
||||
setIsOpen(false);
|
||||
} catch (error) {
|
||||
form.setError("password", {
|
||||
message: "Connection error. Please try again.",
|
||||
|
||||
@@ -14,7 +14,7 @@ import Link from "next/link";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export const GenerateToken = () => {
|
||||
const { data, refetch } = api.auth.get.useQuery();
|
||||
const { data, refetch } = api.user.get.useQuery();
|
||||
|
||||
const { mutateAsync: generateToken, isLoading: isLoadingToken } =
|
||||
api.auth.generateToken.useMutation();
|
||||
|
||||
@@ -59,7 +59,7 @@ export const ProfileForm = () => {
|
||||
const utils = api.useUtils();
|
||||
const { mutateAsync: disable2FA, isLoading: isDisabling } =
|
||||
api.auth.disable2FA.useMutation();
|
||||
const { data, refetch, isLoading } = api.auth.get.useQuery();
|
||||
const { data, refetch, isLoading } = api.user.get.useQuery();
|
||||
const {
|
||||
mutateAsync,
|
||||
isLoading: isUpdating,
|
||||
|
||||
@@ -35,7 +35,7 @@ const profileSchema = z.object({
|
||||
type Profile = z.infer<typeof profileSchema>;
|
||||
|
||||
export const RemoveSelfAccount = () => {
|
||||
const { data } = api.auth.get.useQuery();
|
||||
const { data } = api.user.get.useQuery();
|
||||
const { mutateAsync, isLoading, error, isError } =
|
||||
api.auth.removeSelfAccount.useMutation();
|
||||
const { t } = useTranslation("settings");
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Props {
|
||||
serverId?: string;
|
||||
}
|
||||
export const ToggleDockerCleanup = ({ serverId }: Props) => {
|
||||
const { data, refetch } = api.admin.one.useQuery(undefined, {
|
||||
const { data, refetch } = api.user.get.useQuery(undefined, {
|
||||
enabled: !serverId,
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ export const ToggleDockerCleanup = ({ serverId }: Props) => {
|
||||
},
|
||||
);
|
||||
|
||||
const enabled = data?.enableDockerCleanup || server?.enableDockerCleanup;
|
||||
const enabled = data?.user.enableDockerCleanup || server?.enableDockerCleanup;
|
||||
|
||||
const { mutateAsync } = api.settings.updateDockerCleanup.useMutation();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ export const SetupMonitoring = ({ serverId }: Props) => {
|
||||
enabled: !!serverId,
|
||||
},
|
||||
)
|
||||
: api.admin.one.useQuery();
|
||||
: api.user.get.useQuery();
|
||||
|
||||
const url = useUrl();
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export const AddUserPermissions = ({ userId }: Props) => {
|
||||
);
|
||||
|
||||
const { mutateAsync, isError, error, isLoading } =
|
||||
api.admin.assignPermissions.useMutation();
|
||||
api.user.assignPermissions.useMutation();
|
||||
|
||||
const form = useForm<AddPermissions>({
|
||||
defaultValues: {
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { api } from "@/utils/api";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { format } from "date-fns";
|
||||
import { format, isPast } from "date-fns";
|
||||
import { Mail, MoreHorizontal, Users } from "lucide-react";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
@@ -35,8 +35,6 @@ import { AddInvitation } from "./add-invitation";
|
||||
export const ShowInvitations = () => {
|
||||
const { data, isLoading, refetch } =
|
||||
api.organization.allInvitations.useQuery();
|
||||
const { mutateAsync, isLoading: isRemoving } =
|
||||
api.admin.removeUser.useMutation();
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
@@ -84,6 +82,9 @@ export const ShowInvitations = () => {
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data?.map((invitation) => {
|
||||
const isExpired = isPast(
|
||||
new Date(invitation.expiresAt),
|
||||
);
|
||||
return (
|
||||
<TableRow key={invitation.id}>
|
||||
<TableCell className="w-[100px]">
|
||||
@@ -104,17 +105,22 @@ export const ShowInvitations = () => {
|
||||
<Badge
|
||||
variant={
|
||||
invitation.status === "pending"
|
||||
? "default"
|
||||
? "secondary"
|
||||
: invitation.status === "canceled"
|
||||
? "destructive"
|
||||
: "secondary"
|
||||
: "default"
|
||||
}
|
||||
>
|
||||
{invitation.status}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{format(new Date(invitation.expiresAt), "PPpp")}
|
||||
{format(new Date(invitation.expiresAt), "PPpp")}{" "}
|
||||
{isExpired ? (
|
||||
<span className="text-muted-foreground">
|
||||
(Expired)
|
||||
</span>
|
||||
) : null}
|
||||
</TableCell>
|
||||
|
||||
<TableCell className="text-right flex justify-end">
|
||||
@@ -132,44 +138,51 @@ export const ShowInvitations = () => {
|
||||
<DropdownMenuLabel>
|
||||
Actions
|
||||
</DropdownMenuLabel>
|
||||
{!isExpired && (
|
||||
<>
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={(e) => {
|
||||
copy(
|
||||
`${origin}/invitation?token=${invitation.id}`,
|
||||
);
|
||||
toast.success(
|
||||
"Invitation Copied to clipboard",
|
||||
);
|
||||
}}
|
||||
>
|
||||
Copy Invitation
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={(e) => {
|
||||
copy(
|
||||
`${origin}/invitation?token=${invitation.id}`,
|
||||
);
|
||||
toast.success(
|
||||
"Invitation Copied to clipboard",
|
||||
);
|
||||
}}
|
||||
>
|
||||
Copy Invitation
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={async (e) => {
|
||||
const result =
|
||||
await authClient.organization.cancelInvitation(
|
||||
{
|
||||
invitationId: invitation.id,
|
||||
},
|
||||
);
|
||||
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={async (e) => {
|
||||
const result =
|
||||
await authClient.organization.cancelInvitation(
|
||||
{
|
||||
invitationId: invitation.id,
|
||||
},
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
toast.error(result.error.message);
|
||||
} else {
|
||||
toast.success("Invitation deleted");
|
||||
refetch();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Cancel Invitation
|
||||
</DropdownMenuItem>
|
||||
if (result.error) {
|
||||
toast.error(
|
||||
result.error.message,
|
||||
);
|
||||
} else {
|
||||
toast.success(
|
||||
"Invitation deleted",
|
||||
);
|
||||
refetch();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Cancel Invitation
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -75,9 +75,7 @@ export const ShowUsers = () => {
|
||||
<TableHead className="w-[100px]">Email</TableHead>
|
||||
<TableHead className="text-center">Role</TableHead>
|
||||
<TableHead className="text-center">2FA</TableHead>
|
||||
<TableHead className="text-center">
|
||||
Is Registered
|
||||
</TableHead>
|
||||
|
||||
<TableHead className="text-center">
|
||||
Created At
|
||||
</TableHead>
|
||||
@@ -108,12 +106,6 @@ export const ShowUsers = () => {
|
||||
: "Disabled"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{member.user.isRegistered ||
|
||||
member.role === "owner"
|
||||
? "Registered"
|
||||
: "Not Registered"}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{format(new Date(member.createdAt), "PPpp")}
|
||||
</span>
|
||||
@@ -134,22 +126,6 @@ export const ShowUsers = () => {
|
||||
<DropdownMenuLabel>
|
||||
Actions
|
||||
</DropdownMenuLabel>
|
||||
{!member.user.isRegistered &&
|
||||
member.role !== "owner" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={(e) => {
|
||||
copy(
|
||||
`${origin}/invitation?token=${member.user.token}`,
|
||||
);
|
||||
toast.success(
|
||||
"Invitation Copied to clipboard",
|
||||
);
|
||||
}}
|
||||
>
|
||||
Copy Invitation
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{member.role !== "owner" && (
|
||||
<AddUserPermissions
|
||||
|
||||
@@ -52,7 +52,7 @@ type AddServerDomain = z.infer<typeof addServerDomain>;
|
||||
|
||||
export const WebDomain = () => {
|
||||
const { t } = useTranslation("settings");
|
||||
const { data, refetch } = api.auth.get.useQuery();
|
||||
const { data, refetch } = api.user.get.useQuery();
|
||||
const { mutateAsync, isLoading } =
|
||||
api.settings.assignDomainServer.useMutation();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ interface Props {
|
||||
}
|
||||
export const WebServer = ({ className }: Props) => {
|
||||
const { t } = useTranslation("settings");
|
||||
const { data } = api.admin.one.useQuery();
|
||||
const { data } = api.user.get.useQuery();
|
||||
|
||||
const { data: dokployVersion } = api.settings.getDokployVersion.useQuery();
|
||||
|
||||
@@ -58,7 +58,7 @@ export const WebServer = ({ className }: Props) => {
|
||||
|
||||
<div className="flex items-center flex-wrap justify-between gap-4">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Server IP: {data?.serverIp}
|
||||
Server IP: {data?.user.serverIp}
|
||||
</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Version: {dokployVersion}
|
||||
|
||||
@@ -54,7 +54,7 @@ export const UpdateServerIp = ({ children, serverId }: Props) => {
|
||||
|
||||
const form = useForm<Schema>({
|
||||
defaultValues: {
|
||||
serverIp: data?.serverIp || "",
|
||||
serverIp: data?.user.serverIp || "",
|
||||
},
|
||||
resolver: zodResolver(schema),
|
||||
});
|
||||
@@ -62,7 +62,7 @@ export const UpdateServerIp = ({ children, serverId }: Props) => {
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
form.reset({
|
||||
serverIp: data.serverIp || "",
|
||||
serverIp: data.user.serverIp || "",
|
||||
});
|
||||
}
|
||||
}, [form, form.reset, data]);
|
||||
|
||||
Reference in New Issue
Block a user