React components, UI library, state management ve user experience geliştirmek için kullanılır. Zustand, TanStack Query, Tailwind CSS ve accessibility konularında uzman.
React components, UI library, state management ve user experience geliştirir.
src/components/
├── ui/ # Radix UI components
│ ├── button.tsx
│ ├── input.tsx
│ ├── dialog.tsx
│ └── ...
├── shared/ # Shared application components
│ ├── data-table.tsx
│ ├── stat-card.tsx
│ ├── empty-state.tsx
│ └── ...
└── features/ # Feature-specific components
├── members/
├── donations/
└── social-aid/
import { cn } from "@/lib/utils";
interface StatCardProps {
title: string;
value: string | number;
description?: string;
icon?: React.ReactNode;
trend?: "up" | "down" | "neutral";
className?: string;
}
export function StatCard({
title,
value,
description,
icon,
trend,
className,
}: StatCardProps) {
return (
<div
className={cn(
"rounded-lg border bg-card p-6 shadow-sm",
className
)}
>
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-muted-foreground">
{title}
</p>
{icon && (
<div className="text-muted-foreground">{icon}</div>
)}
</div>
<div className="mt-2">
<p className="text-2xl font-bold">{value}</p>
{description && (
<p className="text-xs text-muted-foreground mt-1">
{description}
</p>
)}
</div>
</div>
);
}
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
// Fetch members
export function useMembers() {
return useQuery({
queryKey: ["members"],
queryFn: async () => {
const res = await fetch("/api/members");
if (!res.ok) throw new Error("Üyeler yüklenemedi");
return res.json();
},
});
}
// Create member mutation
export function useCreateMember() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (data: CreateMemberInput) => {
const res = await fetch("/api/members", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (!res.ok) throw new Error("Üye oluşturulamadı");
return res.json();
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["members"] });
},
});
}
import { create } from "zustand";
import { persist } from "zustand/middleware";
interface SidebarState {
isOpen: boolean;
toggle: () => void;
setOpen: (open: boolean) => void;
}
export const useSidebarStore = create<SidebarState>()(
persist(
(set) => ({
isOpen: true,
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
setOpen: (open) => set({ isOpen: open }),
}),
{
name: "sidebar-storage",
}
)
);