forked from baron/baron-sso
style: perfectly align title, description, and search controls in a single row
- Use flex-row and items-baseline to seamlessly integrate the title and description. - Remove input labels to streamline the search bar vertically. - Apply mr-auto to the title group to push the search controls exactly to the right while keeping everything on the same horizontal baseline.
This commit is contained in:
@@ -474,35 +474,30 @@ function TenantListPage() {
|
||||
</header>
|
||||
|
||||
<Card className="bg-[var(--color-panel)] flex-1 flex flex-col min-h-0 overflow-hidden">
|
||||
<CardHeader className="flex flex-wrap items-end gap-8 flex-shrink-0">
|
||||
<div>
|
||||
<CardTitle>
|
||||
<CardHeader className="flex flex-row items-center gap-4 py-4 flex-wrap flex-shrink-0">
|
||||
<div className="flex items-baseline gap-3 flex-shrink-0 mr-auto">
|
||||
<CardTitle className="text-lg m-0">
|
||||
{t("ui.admin.tenants.registry.title", "Tenant Registry")}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<CardDescription className="m-0">
|
||||
{t("msg.admin.tenants.registry.count", "총 {{count}}개 테넌트", {
|
||||
count: query.data?.total ?? 0,
|
||||
})}
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
<div className="flex items-end gap-4">
|
||||
<div className="relative flex-1 min-w-[240px] max-w-sm">
|
||||
<label className="text-xs font-medium text-muted-foreground mb-1.5 block">
|
||||
{t("ui.admin.tenants.list.search_label", "테넌트 검색")}
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={t(
|
||||
"ui.admin.tenants.list.search_placeholder",
|
||||
"테넌트 이름 또는 슬러그 검색...",
|
||||
)}
|
||||
className="pl-9"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="relative w-[280px]">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={t(
|
||||
"ui.admin.tenants.list.search_placeholder",
|
||||
"테넌트 이름 또는 슬러그 검색...",
|
||||
)}
|
||||
className="pl-9 h-9"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
@@ -465,12 +465,12 @@ function UserListPage() {
|
||||
</header>
|
||||
|
||||
<Card className="flex-1 flex flex-col min-h-0 bg-[var(--color-panel)] overflow-hidden">
|
||||
<CardHeader className="flex flex-wrap items-end gap-8 flex-shrink-0">
|
||||
<div>
|
||||
<CardTitle>
|
||||
<CardHeader className="flex flex-row items-center gap-4 py-4 flex-wrap flex-shrink-0">
|
||||
<div className="flex items-baseline gap-3 flex-shrink-0 mr-auto">
|
||||
<CardTitle className="text-lg m-0">
|
||||
{t("ui.admin.users.list.registry.title", "사용자 레지스트리")}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<CardDescription className="m-0">
|
||||
{t(
|
||||
"msg.admin.users.list.registry.count",
|
||||
"총 {{count}}명의 사용자가 등록되어 있습니다.",
|
||||
@@ -479,32 +479,27 @@ function UserListPage() {
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
<div className="flex items-end gap-4">
|
||||
<div className="relative flex-1 min-w-[240px] max-w-sm">
|
||||
<label className="text-xs font-medium text-muted-foreground mb-1.5 block">
|
||||
{t("ui.admin.users.list.search_label", "사용자 검색")}
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={t(
|
||||
"ui.admin.users.list.search_placeholder",
|
||||
"이름 또는 이메일 검색...",
|
||||
)}
|
||||
className="pl-9"
|
||||
value={searchDraft}
|
||||
onChange={(e) => setSearchDraft(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="relative w-[240px]">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={t(
|
||||
"ui.admin.users.list.search_placeholder",
|
||||
"이름 또는 이메일 검색...",
|
||||
)}
|
||||
className="pl-9 h-9"
|
||||
value={searchDraft}
|
||||
onChange={(e) => setSearchDraft(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<span className="text-xs font-medium text-muted-foreground whitespace-nowrap">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium text-muted-foreground whitespace-nowrap">
|
||||
{t("ui.admin.users.list.filter.tenant", "테넌트 필터")}
|
||||
</span>
|
||||
<select
|
||||
className="flex h-9 w-[200px] rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
||||
className="flex h-9 w-[180px] rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
||||
value={selectedCompany}
|
||||
onChange={(e) => {
|
||||
setSelectedCompany(e.target.value);
|
||||
@@ -524,7 +519,7 @@ function UserListPage() {
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={handleSearch}
|
||||
className="mb-0.5"
|
||||
className="h-9"
|
||||
>
|
||||
{t("ui.common.search", "검색")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user