feat(i18n): add i18n for organization management

This commit is contained in:
JiPai 2025-03-09 22:09:27 +08:00
parent 3e522b9cae
commit 888e904d75
4 changed files with 79 additions and 18 deletions

View File

@ -21,6 +21,7 @@ import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, Plus } from "lucide-react";
import { useTranslation } from "next-i18next";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
@ -41,6 +42,7 @@ interface Props {
}
export function AddOrganization({ organizationId }: Props) {
const { t } = useTranslation("common");
const [open, setOpen] = useState(false);
const utils = api.useUtils();
const { data: organization } = api.organization.one.useQuery(
@ -81,7 +83,9 @@ export function AddOrganization({ organizationId }: Props) {
.then(() => {
form.reset();
toast.success(
`Organization ${organizationId ? "updated" : "created"} successfully`,
organizationId
? t("common.side.organizations.updateSuccess")
: t("common.side.organizations.createSuccess"),
);
utils.organization.all.invalidate();
setOpen(false);
@ -89,7 +93,9 @@ export function AddOrganization({ organizationId }: Props) {
.catch((error) => {
console.error(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" />
</div>
<div className="font-medium text-muted-foreground">
Add organization
{t("common.side.organizations.createOrganization")}
</div>
</DropdownMenuItem>
)}
@ -121,12 +127,14 @@ export function AddOrganization({ organizationId }: Props) {
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>
{organizationId ? "Update organization" : "Add organization"}
{organizationId
? t("common.side.organizations.updateOrganization")
: t("common.side.organizations.createOrganization")}
</DialogTitle>
<DialogDescription>
{organizationId
? "Update the organization name and logo"
: "Create a new organization to manage your projects."}
? t("common.side.organizations.updateOrganizationDescription")
: t("common.side.organizations.createOrganizationDescription")}
</DialogDescription>
</DialogHeader>
<Form {...form}>
@ -139,10 +147,14 @@ export function AddOrganization({ organizationId }: Props) {
name="name"
render={({ field }) => (
<FormItem className="tems-center gap-4">
<FormLabel className="text-right">Name</FormLabel>
<FormLabel className="text-right">
{t("common.side.organizations.name")}
</FormLabel>
<FormControl>
<Input
placeholder="Organization name"
placeholder={t(
"common.side.organizations.name.placeHolder",
)}
{...field}
className="col-span-3"
/>
@ -156,7 +168,9 @@ export function AddOrganization({ organizationId }: Props) {
name="logo"
render={({ field }) => (
<FormItem className=" gap-4">
<FormLabel className="text-right">Logo URL</FormLabel>
<FormLabel className="text-right">
{t("common.side.organizations.logoURL")}
</FormLabel>
<FormControl>
<Input
placeholder="https://example.com/logo.png"
@ -171,7 +185,9 @@ export function AddOrganization({ organizationId }: Props) {
/>
<DialogFooter className="mt-4">
<Button type="submit" isLoading={isLoading}>
{organizationId ? "Update organization" : "Create organization"}
{organizationId
? t("common.side.organizations.updateOrganization")
: t("common.side.organizations.createOrganization")}
</Button>
</DialogFooter>
</form>

View File

@ -603,7 +603,8 @@ function SidebarLogo() {
)}
>
<p className="text-sm font-medium leading-none">
{activeOrganization?.name ?? "Select Organization"}
{activeOrganization?.name ??
t("common.side.organizations.select-organization")}
</p>
</div>
</div>
@ -619,7 +620,7 @@ function SidebarLogo() {
sideOffset={4}
>
<DropdownMenuLabel className="text-xs text-muted-foreground">
Organizations
{t("common.side.organizations")}
</DropdownMenuLabel>
{organizations?.map((org) => (
<div className="flex flex-row justify-between" key={org.name}>
@ -647,8 +648,12 @@ function SidebarLogo() {
<div className="flex items-center gap-2">
<AddOrganization organizationId={org.id} />
<DialogAction
title="Delete Organization"
description="Are you sure you want to delete this organization?"
title={t(
"common.side.organizations.delete-organization",
)}
description={t(
"common.side.organizations.confirm-delete-organization",
)}
type="destructive"
onClick={async () => {
await deleteOrganization({
@ -657,13 +662,17 @@ function SidebarLogo() {
.then(() => {
refetch();
toast.success(
"Organization deleted successfully",
t(
"common.side.organizations.organization-deleted",
),
);
})
.catch((error) => {
toast.error(
error?.message ||
"Error deleting organization",
t(
"common.side.organizations.error-deleting-organization",
),
);
});
}}

View File

@ -33,5 +33,23 @@
"common.side.invitations.error-accepting-invitation": "Error accepting invitation",
"common.side.invitations.invitation-accepted": "Invitation accepted successfully",
"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"
}

View File

@ -33,5 +33,23 @@
"common.side.invitations.error-accepting-invitation": "接受邀请时出错",
"common.side.invitations.invitation-accepted": "邀请已成功接受",
"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": "更新组织失败"
}