1
0
forked from baron/baron-sso

페이지 헤더 스타일 통일

This commit is contained in:
2026-05-19 17:28:54 +09:00
parent 528ceea754
commit c2dbc8fc88
14 changed files with 150 additions and 164 deletions

View File

@@ -1,15 +1,16 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
ArrowLeft,
ChevronLeft,
ChevronRight,
Download,
Filter,
Search,
ShieldHalf,
} from "lucide-react";
import { useState } from "react";
import { Link, useParams } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import {
commonStickyTableHeaderClass,
commonTableShellClass,
@@ -194,21 +195,13 @@ function ClientConsentsPage() {
)}
</span>
</nav>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" asChild>
<Link to={`/clients/${clientId}`}>
<ArrowLeft className="h-4 w-4" />
</Link>
</Button>
<div>
<p className="text-3xl font-black leading-tight">
{t(
"ui.dev.clients.consents.title",
"User Consent Grants",
)}
</p>
</div>
</div>
<PageHeader
icon={<ShieldHalf size={20} />}
title={t(
"ui.dev.clients.consents.title",
"User Consent Grants",
)}
/>
</div>
</div>
<ClientDetailTabs activeTab="consents" clientId={clientId} />
@@ -242,24 +235,14 @@ function ClientConsentsPage() {
)}
</span>
</nav>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" asChild>
<Link to={`/clients/${clientId}`}>
<ArrowLeft className="h-4 w-4" />
</Link>
</Button>
<div>
<p className="text-3xl font-black leading-tight">
{t("ui.dev.clients.consents.title", "User Consent Grants")}
</p>
<p className="text-muted-foreground">
{t(
"msg.dev.clients.consents.subtitle",
"OIDC Relying Party 사용자 권한을 검토·관리합니다.",
)}
</p>
</div>
</div>
<PageHeader
icon={<ShieldHalf size={20} />}
title={t("ui.dev.clients.consents.title", "User Consent Grants")}
description={t(
"msg.dev.clients.consents.subtitle",
"OIDC Relying Party 사용자 권한을 검토·관리합니다.",
)}
/>
</div>
<div className="flex items-center gap-3">
<Badge
@@ -623,7 +606,7 @@ function ClientConsentsPage() {
"Active Grants",
)}
</p>
<CardTitle className="text-2xl font-black">
<CardTitle className="text-xl font-semibold">
{rows.filter((r) => r.status === "active").length}
</CardTitle>
</CardHeader>
@@ -636,7 +619,7 @@ function ClientConsentsPage() {
"Total Scopes Issued",
)}
</p>
<CardTitle className="text-2xl font-black">
<CardTitle className="text-xl font-semibold">
{rows.reduce((acc, row) => acc + row.grantedScopes.length, 0)}
</CardTitle>
</CardHeader>
@@ -649,7 +632,7 @@ function ClientConsentsPage() {
"Avg. Scopes per User",
)}
</p>
<CardTitle className="text-2xl font-black">
<CardTitle className="text-xl font-semibold">
{rows.length > 0
? (
rows.reduce(

View File

@@ -1,16 +1,17 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
ArrowLeft,
Eye,
EyeOff,
Link2,
RefreshCw,
Save,
Shield,
ShieldHalf,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
@@ -246,36 +247,26 @@ function ClientDetailsPage() {
{t("ui.dev.clients.details.tab.connection", "Federation")}
</span>
</nav>
<div className="flex flex-wrap items-start justify-between gap-3">
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" asChild>
<Link to="/clients">
<ArrowLeft className="h-4 w-4" />
</Link>
</Button>
<div>
<h1 className="text-4xl font-black leading-tight tracking-tight">
{client?.name || client?.id || clientId}
</h1>
<p className="text-muted-foreground">
{t(
"msg.dev.clients.details.subtitle",
"Manage OIDC credentials and endpoints.",
)}
</p>
</div>
</div>
<Badge
variant={client?.status === "active" ? "info" : "muted"}
className="px-3 py-1 text-xs uppercase"
>
{client?.status === "active"
? t("ui.common.status.active", "Active")
: client?.status === "inactive"
? t("ui.common.status.inactive", "Inactive")
: t("msg.common.loading", "Loading...")}
</Badge>
</div>
<PageHeader
icon={<ShieldHalf size={20} />}
title={client?.name || client?.id || clientId}
description={t(
"msg.dev.clients.details.subtitle",
"Manage OIDC credentials and endpoints.",
)}
actions={
<Badge
variant={client?.status === "active" ? "info" : "muted"}
className="px-3 py-1 text-xs uppercase"
>
{client?.status === "active"
? t("ui.common.status.active", "Active")
: client?.status === "inactive"
? t("ui.common.status.inactive", "Inactive")
: t("msg.common.loading", "Loading...")}
</Badge>
}
/>
<ClientDetailTabs activeTab="connection" clientId={clientId} />
</div>

View File

@@ -1,7 +1,6 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
ArrowLeft,
Check,
ExternalLink,
Info,
@@ -9,6 +8,7 @@ import {
Save,
Search,
Shield,
ShieldHalf,
Sparkles,
Trash2,
Upload,
@@ -17,6 +17,7 @@ import {
import { useEffect, useState } from "react";
import { useAuth } from "react-oidc-context";
import { Link, useNavigate, useParams } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
@@ -1195,26 +1196,18 @@ function ClientGeneralPage() {
</>
)}
</nav>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" asChild>
<Link to={isCreate ? "/clients" : `/clients/${clientId}`}>
<ArrowLeft className="h-4 w-4" />
</Link>
</Button>
<div>
<h1 className="text-3xl font-black leading-tight">
{isCreate
? t("ui.dev.clients.general.title_create", "Create Client")
: t("ui.dev.clients.general.title_edit", "Client Settings")}
</h1>
<p className="text-muted-foreground">
{t(
"ui.dev.clients.general.subtitle",
"앱 정보, 권한 스코프, 보안 설정을 관리합니다.",
)}
</p>
</div>
</div>
<PageHeader
icon={<ShieldHalf size={20} />}
title={
isCreate
? t("ui.dev.clients.general.title_create", "Create Client")
: t("ui.dev.clients.general.title_edit", "Client Settings")
}
description={t(
"ui.dev.clients.general.subtitle",
"앱 정보, 권한 스코프, 보안 설정을 관리합니다.",
)}
/>
</div>
{!isCreate && (
<Badge

View File

@@ -1,9 +1,10 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { ArrowLeft, Info, Link2, Plus, Trash2, X } from "lucide-react";
import { Info, Link2, Plus, ShieldHalf, Trash2, X } from "lucide-react";
import { useDeferredValue, useMemo, useState } from "react";
import { useAuth } from "react-oidc-context";
import { Link, useParams } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
@@ -352,27 +353,14 @@ function ClientRelationsPage() {
{t("ui.dev.clients.details.tab.relationships", "Relationships")}
</span>
</nav>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" asChild>
<Link to={`/clients/${clientId}`}>
<ArrowLeft className="h-4 w-4" />
</Link>
</Button>
<div>
<p className="text-3xl font-black leading-tight">
{t(
"ui.dev.clients.relationships.title",
"Client Relationships",
)}
</p>
<p className="text-muted-foreground">
{t(
"msg.dev.clients.relationships.subtitle",
"RP direct operator relation을 조회하고 User 단위로 추가·삭제합니다.",
)}
</p>
</div>
</div>
<PageHeader
icon={<ShieldHalf size={20} />}
title={t("ui.dev.clients.relationships.title", "Client Relationships")}
description={t(
"msg.dev.clients.relationships.subtitle",
"RP direct operator relation을 조회하고 User 단위로 추가·삭제합니다.",
)}
/>
</div>
<div className="flex items-center gap-3">
<Badge

View File

@@ -1,6 +1,6 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { BookOpenText, Filter, Plus, Search, X } from "lucide-react";
import { BookOpenText, Filter, Plus, Search, ShieldHalf, X } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { useAuth } from "react-oidc-context";
import { Link, useNavigate } from "react-router-dom";
@@ -262,6 +262,7 @@ function ClientsPage() {
return (
<div className="space-y-8">
<PageHeader
icon={<ShieldHalf size={20} />}
title={t("ui.dev.clients.registry.subtitle", "연동 앱")}
description={t(
"msg.dev.clients.registry.description",

View File

@@ -1,7 +1,8 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Edit, Globe, Plus, Save, Trash2 } from "lucide-react";
import { Edit, Plus, Save, ShieldHalf, Trash2 } from "lucide-react";
import { useState } from "react";
import { useParams } from "react-router-dom";
import { PageHeader } from "../../../../../common/core/components/page";
import { Button } from "../../../components/ui/button";
import {
Card,
@@ -195,24 +196,20 @@ export function ClientFederationPage() {
return (
<div className="space-y-6 p-1">
<header className="flex flex-wrap items-center justify-between gap-4">
<div>
<h1 className="text-2xl font-bold flex items-center gap-2">
<Globe className="h-6 w-6 text-primary" />
{t("ui.dev.clients.federation.title", "Identity Federation")}
</h1>
<p className="text-muted-foreground">
{t(
"msg.dev.clients.federation.subtitle",
"Manage external identity providers for this application.",
)}
</p>
</div>
<Button onClick={() => setCreateModalOpen(true)} className="gap-2">
<Plus className="h-4 w-4" />
{t("ui.dev.clients.federation.add_btn", "Add Provider")}
</Button>
</header>
<PageHeader
icon={<ShieldHalf size={20} />}
title={t("ui.dev.clients.federation.title", "Identity Federation")}
description={t(
"msg.dev.clients.federation.subtitle",
"Manage external identity providers for this application.",
)}
actions={
<Button onClick={() => setCreateModalOpen(true)} className="gap-2">
<Plus className="h-4 w-4" />
{t("ui.dev.clients.federation.add_btn", "Add Provider")}
</Button>
}
/>
<Card className="glass-panel">
<CardContent className="p-0">