feat(admin): Server Action'larla kullanıcı yönetimi ve gerçek oturumlu sayfalar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 02:02:00 +03:00
parent 5191a5cce1
commit 2035f73e7d
18 changed files with 437 additions and 270 deletions
@@ -0,0 +1,26 @@
import { Skeleton } from "@/components/ui/skeleton";
import { tr } from "@/i18n/tr";
/** Oturum okunurken gösterilen kabuk iskeleti (yan menü + üst bar + içerik). */
export function AppShellFallback() {
return (
<div role="status" aria-label={tr.common.loading} className="flex min-h-dvh w-full">
<div className="hidden w-64 shrink-0 flex-col gap-3 border-r bg-sidebar p-3 md:flex">
<Skeleton className="h-8 w-28" />
{Array.from({ length: 8 }, (_, i) => (
<Skeleton key={i} className="h-7 w-full" />
))}
</div>
<div className="flex flex-1 flex-col">
<div className="flex h-14 items-center gap-2 border-b px-4">
<Skeleton className="h-8 w-48" />
<Skeleton className="ml-auto size-8 rounded-full" />
</div>
<div className="flex flex-col gap-4 p-4 md:p-6">
<Skeleton className="h-8 w-56" />
<Skeleton className="h-24 w-full" />
</div>
</div>
</div>
);
}
+9 -3
View File
@@ -15,6 +15,7 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import type { SessionUser } from "@/features/auth/types";
import { authClient } from "@/lib/auth-client";
import { tr } from "@/i18n/tr";
export function initials(name: string) {
@@ -30,10 +31,15 @@ export function initials(name: string) {
export function UserMenu({ user, version }: { user: SessionUser; version: string }) {
const router = useRouter();
function logout() {
// FAZ 3: authClient.signOut() sonrası yönlendirme.
async function logout() {
const { error } = await authClient.signOut();
if (error) {
toast.error(tr.common.genericError);
return;
}
toast.success(tr.userMenu.loggedOut);
router.replace("/login");
router.refresh();
}
return (
@@ -61,7 +67,7 @@ export function UserMenu({ user, version }: { user: SessionUser; version: string
</Badge>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive" onSelect={logout}>
<DropdownMenuItem variant="destructive" onSelect={() => void logout()}>
<LogOut />
{tr.userMenu.logout}
</DropdownMenuItem>