mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(i18n): add i18n for organization management
This commit is contained in:
@@ -21,6 +21,7 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { PenBoxIcon, Plus } from "lucide-react";
|
import { PenBoxIcon, Plus } from "lucide-react";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -41,6 +42,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function AddOrganization({ organizationId }: Props) {
|
export function AddOrganization({ organizationId }: Props) {
|
||||||
|
const { t } = useTranslation("common");
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
const { data: organization } = api.organization.one.useQuery(
|
const { data: organization } = api.organization.one.useQuery(
|
||||||
@@ -81,7 +83,9 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
form.reset();
|
form.reset();
|
||||||
toast.success(
|
toast.success(
|
||||||
`Organization ${organizationId ? "updated" : "created"} successfully`,
|
organizationId
|
||||||
|
? t("common.side.organizations.updateSuccess")
|
||||||
|
: t("common.side.organizations.createSuccess"),
|
||||||
);
|
);
|
||||||
utils.organization.all.invalidate();
|
utils.organization.all.invalidate();
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
@@ -89,7 +93,9 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
toast.error(
|
toast.error(
|
||||||
`Failed to ${organizationId ? "update" : "create"} organization`,
|
organizationId
|
||||||
|
? t("common.side.organizations.updateFailed")
|
||||||
|
: t("common.side.organizations.createFailed"),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -113,7 +119,7 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
<Plus className="size-4" />
|
<Plus className="size-4" />
|
||||||
</div>
|
</div>
|
||||||
<div className="font-medium text-muted-foreground">
|
<div className="font-medium text-muted-foreground">
|
||||||
Add organization
|
{t("common.side.organizations.createOrganization")}
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
@@ -121,12 +127,14 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
<DialogContent className="sm:max-w-[425px]">
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{organizationId ? "Update organization" : "Add organization"}
|
{organizationId
|
||||||
|
? t("common.side.organizations.updateOrganization")
|
||||||
|
: t("common.side.organizations.createOrganization")}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
{organizationId
|
{organizationId
|
||||||
? "Update the organization name and logo"
|
? t("common.side.organizations.updateOrganizationDescription")
|
||||||
: "Create a new organization to manage your projects."}
|
: t("common.side.organizations.createOrganizationDescription")}
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
@@ -139,10 +147,14 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
name="name"
|
name="name"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="tems-center gap-4">
|
<FormItem className="tems-center gap-4">
|
||||||
<FormLabel className="text-right">Name</FormLabel>
|
<FormLabel className="text-right">
|
||||||
|
{t("common.side.organizations.name")}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Organization name"
|
placeholder={t(
|
||||||
|
"common.side.organizations.name.placeHolder",
|
||||||
|
)}
|
||||||
{...field}
|
{...field}
|
||||||
className="col-span-3"
|
className="col-span-3"
|
||||||
/>
|
/>
|
||||||
@@ -156,7 +168,9 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
name="logo"
|
name="logo"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className=" gap-4">
|
<FormItem className=" gap-4">
|
||||||
<FormLabel className="text-right">Logo URL</FormLabel>
|
<FormLabel className="text-right">
|
||||||
|
{t("common.side.organizations.logoURL")}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
placeholder="https://example.com/logo.png"
|
placeholder="https://example.com/logo.png"
|
||||||
@@ -171,7 +185,9 @@ export function AddOrganization({ organizationId }: Props) {
|
|||||||
/>
|
/>
|
||||||
<DialogFooter className="mt-4">
|
<DialogFooter className="mt-4">
|
||||||
<Button type="submit" isLoading={isLoading}>
|
<Button type="submit" isLoading={isLoading}>
|
||||||
{organizationId ? "Update organization" : "Create organization"}
|
{organizationId
|
||||||
|
? t("common.side.organizations.updateOrganization")
|
||||||
|
: t("common.side.organizations.createOrganization")}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -603,7 +603,8 @@ function SidebarLogo() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<p className="text-sm font-medium leading-none">
|
<p className="text-sm font-medium leading-none">
|
||||||
{activeOrganization?.name ?? "Select Organization"}
|
{activeOrganization?.name ??
|
||||||
|
t("common.side.organizations.select-organization")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -619,7 +620,7 @@ function SidebarLogo() {
|
|||||||
sideOffset={4}
|
sideOffset={4}
|
||||||
>
|
>
|
||||||
<DropdownMenuLabel className="text-xs text-muted-foreground">
|
<DropdownMenuLabel className="text-xs text-muted-foreground">
|
||||||
Organizations
|
{t("common.side.organizations")}
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
{organizations?.map((org) => (
|
{organizations?.map((org) => (
|
||||||
<div className="flex flex-row justify-between" key={org.name}>
|
<div className="flex flex-row justify-between" key={org.name}>
|
||||||
@@ -647,8 +648,12 @@ function SidebarLogo() {
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<AddOrganization organizationId={org.id} />
|
<AddOrganization organizationId={org.id} />
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Delete Organization"
|
title={t(
|
||||||
description="Are you sure you want to delete this organization?"
|
"common.side.organizations.delete-organization",
|
||||||
|
)}
|
||||||
|
description={t(
|
||||||
|
"common.side.organizations.confirm-delete-organization",
|
||||||
|
)}
|
||||||
type="destructive"
|
type="destructive"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await deleteOrganization({
|
await deleteOrganization({
|
||||||
@@ -657,13 +662,17 @@ function SidebarLogo() {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
refetch();
|
refetch();
|
||||||
toast.success(
|
toast.success(
|
||||||
"Organization deleted successfully",
|
t(
|
||||||
|
"common.side.organizations.organization-deleted",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
toast.error(
|
toast.error(
|
||||||
error?.message ||
|
error?.message ||
|
||||||
"Error deleting organization",
|
t(
|
||||||
|
"common.side.organizations.error-deleting-organization",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -33,5 +33,23 @@
|
|||||||
"common.side.invitations.error-accepting-invitation": "Error accepting invitation",
|
"common.side.invitations.error-accepting-invitation": "Error accepting invitation",
|
||||||
"common.side.invitations.invitation-accepted": "Invitation accepted successfully",
|
"common.side.invitations.invitation-accepted": "Invitation accepted successfully",
|
||||||
"common.side.invitations.expires": "Expires: {{expireDate}}",
|
"common.side.invitations.expires": "Expires: {{expireDate}}",
|
||||||
"common.side.invitations.role": "Role: {{role}}"
|
"common.side.invitations.role": "Role: {{role}}",
|
||||||
|
|
||||||
|
"common.side.organizations": "Organizations",
|
||||||
|
"common.side.organizations.select-organization": "Select Organization",
|
||||||
|
"common.side.organizations.delete-organization": "Delete Organization",
|
||||||
|
"common.side.organizations.confirm-delete-organization": "Are you sure you want to delete this organization?",
|
||||||
|
"common.side.organizations.organization-deleted": "Organization deleted successfully",
|
||||||
|
"common.side.organizations.error-deleting-organization": "Error deleting organization",
|
||||||
|
"common.side.organizations.createOrganization": "Create organization",
|
||||||
|
"common.side.organizations.updateOrganization": "Update organization",
|
||||||
|
"common.side.organizations.createOrganizationDescription": "Create a new organization to manage your projects.",
|
||||||
|
"common.side.organizations.updateOrganizationDescription": "Update the organization name and logo",
|
||||||
|
"common.side.organizations.name": "Name",
|
||||||
|
"common.side.organizations.name.placeHolder": "Organization name",
|
||||||
|
"common.side.organizations.logoURL": "Logo URL",
|
||||||
|
"common.side.organizations.createSuccess": "Organization created successfully",
|
||||||
|
"common.side.organizations.updateSuccess": "Organization updated successfully",
|
||||||
|
"common.side.organizations.createFailed": "Failed to create organization",
|
||||||
|
"common.side.organizations.updateFailed": "Failed to update organization"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,5 +33,23 @@
|
|||||||
"common.side.invitations.error-accepting-invitation": "接受邀请时出错",
|
"common.side.invitations.error-accepting-invitation": "接受邀请时出错",
|
||||||
"common.side.invitations.invitation-accepted": "邀请已成功接受",
|
"common.side.invitations.invitation-accepted": "邀请已成功接受",
|
||||||
"common.side.invitations.expires": "有效期:{{expireDate}}",
|
"common.side.invitations.expires": "有效期:{{expireDate}}",
|
||||||
"common.side.invitations.role": "角色:{{role}}"
|
"common.side.invitations.role": "角色:{{role}}",
|
||||||
|
|
||||||
|
"common.side.organizations": "组织",
|
||||||
|
"common.side.organizations.select-organization": "选择组织",
|
||||||
|
"common.side.organizations.delete-organization": "删除组织",
|
||||||
|
"common.side.organizations.confirm-delete-organization": "您确定要删除此组织吗?",
|
||||||
|
"common.side.organizations.organization-deleted": "组织已成功删除",
|
||||||
|
"common.side.organizations.error-deleting-organization": "删除组织时出错",
|
||||||
|
"common.side.organizations.createOrganization": "创建组织",
|
||||||
|
"common.side.organizations.updateOrganization": "更新组织",
|
||||||
|
"common.side.organizations.createOrganizationDescription": "创建一个新组织来管理您的项目。",
|
||||||
|
"common.side.organizations.updateOrganizationDescription": "更新组织名称和标志",
|
||||||
|
"common.side.organizations.name": "名称",
|
||||||
|
"common.side.organizations.name.placeHolder": "请输入组织名称",
|
||||||
|
"common.side.organizations.logoURL": "Logo 图片地址",
|
||||||
|
"common.side.organizations.createSuccess": "组织创建成功",
|
||||||
|
"common.side.organizations.updateSuccess": "组织更新成功",
|
||||||
|
"common.side.organizations.createFailed": "创建组织失败",
|
||||||
|
"common.side.organizations.updateFailed": "更新组织失败"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user