forked from baron/baron-sso
페이지 헤더 레이아웃 공통화
This commit is contained in:
@@ -20,9 +20,6 @@ import { Button } from "../../components/ui/button";
|
|||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "../../components/ui/card";
|
} from "../../components/ui/card";
|
||||||
import { Input } from "../../components/ui/input";
|
import { Input } from "../../components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -33,6 +30,7 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
import type { DevAuditLog } from "../../lib/devApi";
|
import type { DevAuditLog } from "../../lib/devApi";
|
||||||
import { fetchDevAuditLogs } from "../../lib/devApi";
|
import { fetchDevAuditLogs } from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
@@ -194,23 +192,15 @@ function AuditLogsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<Card className="glass-panel">
|
<PageHeader
|
||||||
<CardHeader className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
|
eyebrow={t("ui.dev.audit.registry.title", "Audit registry")}
|
||||||
<div>
|
title={t("ui.dev.audit.title", "Audit Logs")}
|
||||||
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">
|
description={t(
|
||||||
{t("ui.dev.audit.registry.title", "Audit registry")}
|
"msg.dev.audit.subtitle",
|
||||||
</p>
|
"Shows DevFront activity history within current tenant/app scope.",
|
||||||
<CardTitle className="text-3xl font-black tracking-tight">
|
)}
|
||||||
{t("ui.dev.audit.title", "Audit Logs")}
|
actions={
|
||||||
</CardTitle>
|
<>
|
||||||
<CardDescription>
|
|
||||||
{t(
|
|
||||||
"msg.dev.audit.subtitle",
|
|
||||||
"Shows DevFront activity history within current tenant/app scope.",
|
|
||||||
)}
|
|
||||||
</CardDescription>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Badge variant="muted">
|
<Badge variant="muted">
|
||||||
{t("msg.dev.audit.loaded_count", "Loaded {{count}} rows", {
|
{t("msg.dev.audit.loaded_count", "Loaded {{count}} rows", {
|
||||||
count: logs.length,
|
count: logs.length,
|
||||||
@@ -231,9 +221,12 @@ function AuditLogsPage() {
|
|||||||
<Download size={16} />
|
<Download size={16} />
|
||||||
{t("ui.dev.clients.consents.export_csv", "Export CSV")}
|
{t("ui.dev.clients.consents.export_csv", "Export CSV")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</>
|
||||||
</CardHeader>
|
}
|
||||||
<CardContent className="space-y-4">
|
/>
|
||||||
|
|
||||||
|
<Card className="glass-panel">
|
||||||
|
<CardContent className="space-y-4 pt-6">
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
sortableTableHeadBaseClassName,
|
sortableTableHeadBaseClassName,
|
||||||
sortableTableHeaderClassName,
|
sortableTableHeaderClassName,
|
||||||
} from "../../../../common/core/components/sort";
|
} from "../../../../common/core/components/sort";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
import {
|
import {
|
||||||
type SortConfig,
|
type SortConfig,
|
||||||
type SortResolverMap,
|
type SortResolverMap,
|
||||||
@@ -259,37 +260,30 @@ function ClientsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
|
<PageHeader
|
||||||
|
eyebrow={t("ui.dev.clients.registry.title", "RP registry")}
|
||||||
|
title={t("ui.dev.clients.registry.subtitle", "연동 앱")}
|
||||||
|
description={t(
|
||||||
|
"msg.dev.clients.registry.description",
|
||||||
|
"OIDC 클라이언트, 인증 방식, 리다이렉트 URI, 비밀키 재발행을 감사 로그와 함께 관리합니다.",
|
||||||
|
)}
|
||||||
|
actions={
|
||||||
|
canCreateClient ? (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
className="shadow-lg shadow-primary/30"
|
||||||
|
onClick={() => navigate("/clients/new")}
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
{t("ui.dev.clients.new", "새 클라이언트")}
|
||||||
|
</Button>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Card className="glass-panel">
|
<Card className="glass-panel">
|
||||||
<CardHeader className="pb-4">
|
<CardHeader className="pb-4 pt-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex flex-col gap-3">
|
||||||
<div>
|
|
||||||
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">
|
|
||||||
{t("ui.dev.clients.registry.title", "RP registry")}
|
|
||||||
</p>
|
|
||||||
<CardTitle className="text-3xl font-black tracking-tight">
|
|
||||||
{t("ui.dev.clients.registry.subtitle", "연동 앱")}
|
|
||||||
</CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
{t(
|
|
||||||
"msg.dev.clients.registry.description",
|
|
||||||
"OIDC 클라이언트, 인증 방식, 리다이렉트 URI, 비밀키 재발행을 감사 로그와 함께 관리합니다.",
|
|
||||||
)}
|
|
||||||
</CardDescription>
|
|
||||||
</div>
|
|
||||||
{canCreateClient && (
|
|
||||||
<div className="hidden items-center gap-2 md:flex">
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
className="shadow-lg shadow-primary/30"
|
|
||||||
onClick={() => navigate("/clients/new")}
|
|
||||||
>
|
|
||||||
<Plus className="h-4 w-4" />
|
|
||||||
{t("ui.dev.clients.new", "새 클라이언트")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 flex flex-col gap-3">
|
|
||||||
<div className="flex flex-col gap-3 md:flex-row md:items-center">
|
<div className="flex flex-col gap-3 md:flex-row md:items-center">
|
||||||
<div className="relative flex-1">
|
<div className="relative flex-1">
|
||||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||||
@@ -437,14 +431,6 @@ function ClientsPage() {
|
|||||||
)}
|
)}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
{canCreateClient && (
|
|
||||||
<div className="flex items-center gap-2 md:hidden">
|
|
||||||
<Button size="sm" onClick={() => navigate("/clients/new")}>
|
|
||||||
<Plus className="h-4 w-4" />
|
|
||||||
{t("ui.dev.clients.new", "새 클라이언트")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex-1 flex flex-col min-h-0 pt-0">
|
<CardContent className="flex-1 flex flex-col min-h-0 pt-0">
|
||||||
<div className={commonTableShellClass}>
|
<div className={commonTableShellClass}>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
commonTableShellClass,
|
commonTableShellClass,
|
||||||
commonTableViewportClass,
|
commonTableViewportClass,
|
||||||
} from "../../../../common/ui/table";
|
} from "../../../../common/ui/table";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
import { Textarea } from "../../components/ui/textarea";
|
import { Textarea } from "../../components/ui/textarea";
|
||||||
import {
|
import {
|
||||||
approveDeveloperRequest,
|
approveDeveloperRequest,
|
||||||
@@ -158,30 +159,28 @@ export default function DeveloperRequestPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<PageHeader
|
||||||
<div>
|
title={t("ui.dev.nav.developer_request", "개발자 권한 신청")}
|
||||||
<h1 className="text-3xl font-bold tracking-tight">
|
description={
|
||||||
{t("ui.dev.nav.developer_request", "개발자 권한 신청")}
|
isSuperAdmin
|
||||||
</h1>
|
? t(
|
||||||
<p className="text-muted-foreground mt-1">
|
"msg.dev.request.admin_desc",
|
||||||
{isSuperAdmin
|
"사용자들의 개발자 권한 신청 내역을 관리합니다.",
|
||||||
? t(
|
)
|
||||||
"msg.dev.request.admin_desc",
|
: t(
|
||||||
"사용자들의 개발자 권한 신청 내역을 관리합니다.",
|
"msg.dev.request.user_desc",
|
||||||
)
|
"내 신청 내역을 확인하고 새로운 권한을 신청할 수 있습니다.",
|
||||||
: t(
|
)
|
||||||
"msg.dev.request.user_desc",
|
}
|
||||||
"내 신청 내역을 확인하고 새로운 권한을 신청할 수 있습니다.",
|
actions={
|
||||||
)}
|
!isSuperAdmin && !hasActiveRequest ? (
|
||||||
</p>
|
<Button onClick={() => setIsRequestModalOpen(true)}>
|
||||||
</div>
|
<Plus className="mr-2 h-4 w-4" />
|
||||||
{!isSuperAdmin && !hasActiveRequest && (
|
{t("ui.dev.welcome.btn_request", "신규 신청하기")}
|
||||||
<Button onClick={() => setIsRequestModalOpen(true)}>
|
</Button>
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
) : null
|
||||||
{t("ui.dev.welcome.btn_request", "신규 신청하기")}
|
}
|
||||||
</Button>
|
/>
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Card className="glass-panel">
|
<Card className="glass-panel">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|||||||
Reference in New Issue
Block a user