forked from baron/baron-sso
클라이언트 목록 및 상세 화면에 복사 피드백 적용
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { BadgeCheck, Moon, ShieldHalf, Sun } from "lucide-react";
|
import { BadgeCheck, Moon, ShieldHalf, Sun } from "lucide-react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { NavLink, Outlet } from "react-router-dom";
|
import { NavLink, Outlet } from "react-router-dom";
|
||||||
|
import { Toaster } from "../ui/toaster";
|
||||||
|
|
||||||
const navItems = [{ label: "Clients", to: "/clients", icon: ShieldHalf }];
|
const navItems = [{ label: "Clients", to: "/clients", icon: ShieldHalf }];
|
||||||
|
|
||||||
@@ -105,6 +106,7 @@ function AppLayout() {
|
|||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
<Toaster />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { Textarea } from "../../components/ui/textarea";
|
|||||||
import { Label } from "../../components/ui/label";
|
import { Label } from "../../components/ui/label";
|
||||||
import { fetchClient, updateClient } from "../../lib/devApi";
|
import { fetchClient, updateClient } from "../../lib/devApi";
|
||||||
import { cn } from "../../lib/utils";
|
import { cn } from "../../lib/utils";
|
||||||
|
import { CopyButton } from "../../components/ui/copy-button";
|
||||||
|
import { toast } from "../../components/ui/use-toast";
|
||||||
|
|
||||||
function ClientDetailsPage() {
|
function ClientDetailsPage() {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -48,10 +50,10 @@ function ClientDetailsPage() {
|
|||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["client", clientId] });
|
queryClient.invalidateQueries({ queryKey: ["client", clientId] });
|
||||||
alert("Redirect URIs가 저장되었습니다.");
|
toast("Redirect URIs가 저장되었습니다.");
|
||||||
},
|
},
|
||||||
onError: (err) => {
|
onError: (err) => {
|
||||||
alert(`저장 실패: ${(err as Error).message}`);
|
toast(`저장 실패: ${(err as Error).message}`, "error");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -145,9 +147,10 @@ function ClientDetailsPage() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<p className="font-mono text-lg truncate">{data.client.id}</p>
|
<p className="font-mono text-lg truncate">{data.client.id}</p>
|
||||||
<Button variant="secondary" size="icon" className="shrink-0" onClick={() => navigator.clipboard.writeText(data.client.id)}>
|
<CopyButton
|
||||||
<Copy className="h-4 w-4" />
|
value={data.client.id}
|
||||||
</Button>
|
onCopy={() => toast("Client ID가 복사되었습니다.")}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -173,14 +176,11 @@ function ClientDetailsPage() {
|
|||||||
>
|
>
|
||||||
{showSecret ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
|
{showSecret ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<CopyButton
|
||||||
variant="secondary"
|
value={clientSecret}
|
||||||
size="icon"
|
|
||||||
onClick={() => navigator.clipboard.writeText(clientSecret)}
|
|
||||||
disabled={!showSecret && clientSecret === "SECRET_NOT_AVAILABLE"}
|
disabled={!showSecret && clientSecret === "SECRET_NOT_AVAILABLE"}
|
||||||
>
|
onCopy={() => toast("Client Secret이 복사되었습니다.")}
|
||||||
<Copy className="h-4 w-4" />
|
/>
|
||||||
</Button>
|
|
||||||
<Button variant="outline" size="icon" className="border-amber-500/50 text-amber-500">
|
<Button variant="outline" size="icon" className="border-amber-500/50 text-amber-500">
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -213,14 +213,11 @@ function ClientDetailsPage() {
|
|||||||
<span className="break-all font-mono text-sm">
|
<span className="break-all font-mono text-sm">
|
||||||
{endpoint.value}
|
{endpoint.value}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<CopyButton
|
||||||
variant="secondary"
|
value={endpoint.value}
|
||||||
size="icon"
|
|
||||||
className="h-8 w-8 shrink-0"
|
className="h-8 w-8 shrink-0"
|
||||||
onClick={() => navigator.clipboard.writeText(endpoint.value)}
|
onCopy={() => toast(`${endpoint.label}가 복사되었습니다.`)}
|
||||||
>
|
/>
|
||||||
<Copy className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import {
|
|||||||
updateClientStatus,
|
updateClientStatus,
|
||||||
} from "../../lib/devApi";
|
} from "../../lib/devApi";
|
||||||
import { cn } from "../../lib/utils";
|
import { cn } from "../../lib/utils";
|
||||||
|
import { CopyButton } from "../../components/ui/copy-button";
|
||||||
|
import { toast } from "../../components/ui/use-toast";
|
||||||
|
|
||||||
function ClientsPage() {
|
function ClientsPage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -231,15 +233,13 @@ function ClientsPage() {
|
|||||||
<code className="rounded-md bg-secondary/60 px-2 py-1 font-mono text-xs text-muted-foreground">
|
<code className="rounded-md bg-secondary/60 px-2 py-1 font-mono text-xs text-muted-foreground">
|
||||||
{client.id}
|
{client.id}
|
||||||
</code>
|
</code>
|
||||||
<Button
|
<CopyButton
|
||||||
|
value={client.id}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
|
||||||
className="h-8 w-8 text-muted-foreground hover:text-primary"
|
className="h-8 w-8 text-muted-foreground hover:text-primary"
|
||||||
aria-label="Copy client id"
|
aria-label="Copy client id"
|
||||||
onClick={() => navigator.clipboard.writeText(client.id)}
|
onCopy={() => toast("클라이언트 ID가 복사되었습니다.")}
|
||||||
>
|
/>
|
||||||
<Copy className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
|||||||
Reference in New Issue
Block a user