Implement multi-language support in user management and system management pages

- Integrated multi-language functionality across various user management components, including user list, roles list, and user authorization pages, enhancing accessibility for diverse users.
- Updated UI elements to utilize translation keys, ensuring that all text is dynamically translated based on user preferences.
- Improved error handling messages to be localized, providing a better user experience in case of issues.

These changes significantly enhance the usability and internationalization of the user management features, making the application more inclusive.
This commit is contained in:
kjs
2026-04-01 15:57:12 +09:00
parent 2ff01456dc
commit 1d49fc7ac7
15 changed files with 812 additions and 200 deletions

View File

@@ -651,15 +651,17 @@ export default function I18nPage() {
}
return (
<div className="min-h-screen bg-muted">
<div className="w-full max-w-none px-4 py-8">
<div className="container mx-auto p-2">
<div className="flex h-[calc(100vh-64px)] flex-col bg-muted">
<div className="flex min-h-0 flex-1 flex-col px-4 py-2">
<div className="flex min-h-0 flex-1 flex-col">
{/* 탭 네비게이션 */}
<div className="flex space-x-1 border-b">
<button
onClick={() => setActiveTab("keys")}
className={`rounded-t-lg px-3 py-1.5 text-sm font-medium transition-colors ${
activeTab === "keys" ? "bg-accent0 text-white" : "bg-muted text-foreground hover:bg-muted/80"
activeTab === "keys"
? "border-b-2 border-b-blue-500 bg-white text-blue-600 dark:bg-zinc-900 dark:text-blue-400"
: "text-muted-foreground hover:bg-muted hover:text-foreground"
}`}
>
@@ -667,7 +669,9 @@ export default function I18nPage() {
<button
onClick={() => setActiveTab("languages")}
className={`rounded-t-lg px-3 py-1.5 text-sm font-medium transition-colors ${
activeTab === "languages" ? "bg-accent0 text-white" : "bg-muted text-foreground hover:bg-muted/80"
activeTab === "languages"
? "border-b-2 border-b-blue-500 bg-white text-blue-600 dark:bg-zinc-900 dark:text-blue-400"
: "text-muted-foreground hover:bg-muted hover:text-foreground"
}`}
>
@@ -675,14 +679,14 @@ export default function I18nPage() {
</div>
{/* 메인 콘텐츠 영역 */}
<div className="mt-2">
<div className="mt-2 flex min-h-0 flex-1 flex-col">
{/* 언어 관리 탭 */}
{activeTab === "languages" && (
<Card>
<Card className="flex min-h-0 flex-1 flex-col">
<CardHeader>
<CardTitle> </CardTitle>
</CardHeader>
<CardContent>
<CardContent className="min-h-0 flex-1">
<div className="mb-4 flex items-center justify-between">
<div className="text-sm text-muted-foreground"> {languages.length} .</div>
<div className="flex space-x-2">
@@ -701,16 +705,16 @@ export default function I18nPage() {
{/* 다국어 키 관리 탭 */}
{activeTab === "keys" && (
<div className="grid grid-cols-1 gap-4 lg:grid-cols-12">
<div className="grid min-h-0 flex-1 grid-cols-1 gap-4 lg:grid-cols-12">
{/* 좌측: 카테고리 트리 (2/12) */}
<Card className="lg:col-span-2">
<Card className="flex min-h-0 flex-col lg:col-span-2">
<CardHeader className="py-3">
<div className="flex items-center justify-between">
<CardTitle className="text-sm"></CardTitle>
</div>
</CardHeader>
<CardContent className="p-2">
<ScrollArea className="h-[500px]">
<CardContent className="min-h-0 flex-1 p-2">
<ScrollArea className="h-full">
<CategoryTree
selectedCategoryId={selectedCategory?.categoryId || null}
onSelectCategory={(cat) => setSelectedCategory(cat)}
@@ -724,7 +728,7 @@ export default function I18nPage() {
</Card>
{/* 중앙: 언어 키 목록 (6/12) */}
<Card className="lg:col-span-6">
<Card className="flex min-h-0 flex-col lg:col-span-6">
<CardHeader className="py-3">
<div className="flex items-center justify-between">
<CardTitle className="text-sm">
@@ -758,7 +762,7 @@ export default function I18nPage() {
</div>
</div>
</CardHeader>
<CardContent className="pt-0">
<CardContent className="min-h-0 flex-1 pt-0">
{/* 검색 필터 영역 */}
<div className="mb-2 grid grid-cols-1 gap-2 md:grid-cols-3">
<div>
@@ -806,7 +810,7 @@ export default function I18nPage() {
</Card>
{/* 우측: 선택된 키의 다국어 관리 (4/12) */}
<Card className="lg:col-span-4">
<Card className="flex min-h-0 flex-col lg:col-span-4">
<CardHeader>
<CardTitle>
{selectedKey ? (
@@ -821,11 +825,11 @@ export default function I18nPage() {
)}
</CardTitle>
</CardHeader>
<CardContent>
<CardContent className="min-h-0 flex-1">
{selectedKey ? (
<div>
<div className="flex h-full flex-col">
{/* 스크롤 가능한 텍스트 영역 */}
<div className="max-h-80 space-y-4 overflow-y-auto pr-2">
<div className="min-h-0 flex-1 space-y-4 overflow-y-auto pr-2">
{languages
.filter((lang) => lang.isActive === "Y")
.map((lang) => {
@@ -854,7 +858,7 @@ export default function I18nPage() {
</div>
</div>
) : (
<div className="flex h-64 items-center justify-center text-muted-foreground">
<div className="flex h-full items-center justify-center text-muted-foreground">
<div className="text-center">
<div className="mb-2 text-lg font-medium"> </div>
<div className="text-sm"> </div>