-
+
{children}
diff --git a/app/globals.css b/app/globals.css
index 7e11b97..a494c3f 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,3 +1,4 @@
+@import 'react-phone-number-input/style.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
diff --git a/components/dashboard/header.tsx b/components/dashboard/header.tsx
index b38ed43..7ddc169 100644
--- a/components/dashboard/header.tsx
+++ b/components/dashboard/header.tsx
@@ -6,7 +6,12 @@ import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
import { Sidebar } from "@/components/dashboard/sidebar"
import { UserNav } from "@/components/dashboard/user-nav"
-export function DashboardHeader() {
+interface DashboardHeaderProps {
+ user: { email?: string | null } | null
+ profile: { full_name?: string | null, role?: string | null } | null
+}
+
+export function DashboardHeader({ user, profile }: DashboardHeaderProps) {
return (
)
}
diff --git a/components/dashboard/password-form.tsx b/components/dashboard/password-form.tsx
new file mode 100644
index 0000000..09048d4
--- /dev/null
+++ b/components/dashboard/password-form.tsx
@@ -0,0 +1,113 @@
+"use client"
+
+import { useState } from "react"
+import { useRouter } from "next/navigation"
+import { useForm } from "react-hook-form"
+import { zodResolver } from "@hookform/resolvers/zod"
+import * as z from "zod"
+import { Button } from "@/components/ui/button"
+import { Input } from "@/components/ui/input"
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form"
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { toast } from "sonner"
+import { Loader2 } from "lucide-react"
+import { supabase } from "@/lib/supabase"
+
+const passwordSchema = z.object({
+ password: z.string().min(6, "Şifre en az 6 karakter olmalıdır."),
+ confirmPassword: z.string().min(6, "Şifre tekrarı en az 6 karakter olmalıdır."),
+}).refine((data) => data.password === data.confirmPassword, {
+ message: "Şifreler eşleşmiyor.",
+ path: ["confirmPassword"],
+})
+
+type PasswordFormValues = z.infer
+
+export function PasswordForm() {
+ const router = useRouter()
+ const [loading, setLoading] = useState(false)
+
+ const form = useForm({
+ resolver: zodResolver(passwordSchema),
+ defaultValues: {
+ password: "",
+ confirmPassword: "",
+ },
+ })
+
+ const onSubmit = async (data: PasswordFormValues) => {
+ setLoading(true)
+ try {
+ const { error } = await supabase.auth.updateUser({
+ password: data.password
+ })
+
+ if (error) {
+ toast.error("Şifre güncellenemedi: " + error.message)
+ return
+ }
+
+ toast.success("Şifreniz başarıyla güncellendi.")
+ form.reset()
+ router.refresh()
+ } catch (error) {
+ toast.error("Bir sorun oluştu.")
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ return (
+
+
+ Yeni Şifre Belirle
+
+ Hesabınız için yeni bir şifre belirleyin.
+
+
+
+
+
+
+
+ )
+}
diff --git a/components/dashboard/user-form.tsx b/components/dashboard/user-form.tsx
index 30f36a1..2d6ca02 100644
--- a/components/dashboard/user-form.tsx
+++ b/components/dashboard/user-form.tsx
@@ -7,6 +7,7 @@ import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
+import { PhoneInput } from "@/components/ui/phone-input"
import {
Form,
FormControl,
@@ -25,34 +26,45 @@ import {
import { Card, CardContent } from "@/components/ui/card"
import { toast } from "sonner"
import { Loader2 } from "lucide-react"
-import { createUser, updateUser } from "@/app/(dashboard)/dashboard/users/actions"
+import { createUser, updateUser, updateProfile } from "@/app/(dashboard)/dashboard/users/actions"
const userSchema = z.object({
firstName: z.string().min(2, "Ad en az 2 karakter olmalıdır."),
lastName: z.string().min(2, "Soyad en az 2 karakter olmalıdır."),
email: z.string().email("Geçerli bir e-posta adresi giriniz."),
password: z.string().optional(), // Password is optional on edit
+ confirmPassword: z.string().optional(),
role: z.enum(["admin", "user"]),
+ phone: z.string().optional(),
}).refine((data) => {
- // If we are creating a NEW user (no ID passed in props effectively, but schema doesn't know props),
- // we generally want password required. But here we'll handle it in the component logic or strictly separate schemas.
- // For simplicity, we make password optional in Zod but check it in onSubmit if it's a create action.
+ // 1. Password match check
+ if (data.password && data.password !== data.confirmPassword) {
+ return false;
+ }
+ // 2. New user password requirement check (simplified here, but strict would check id)
+ // We handle the "required" part in onSubmit manually for now as per previous logic,
+ // but the matching check is now here.
return true
+}, {
+ message: "Şifreler eşleşmiyor.",
+ path: ["confirmPassword"],
})
type UserFormValues = z.infer
interface UserFormProps {
initialData?: {
- id: string
+ id?: string
firstName: string
lastName: string
email: string
role: "admin" | "user"
+ phone?: string
}
+ mode?: "admin" | "profile"
}
-export function UserForm({ initialData }: UserFormProps) {
+export function UserForm({ initialData, mode = "admin" }: UserFormProps) {
const router = useRouter()
const [loading, setLoading] = useState(false)
@@ -63,13 +75,17 @@ export function UserForm({ initialData }: UserFormProps) {
lastName: initialData.lastName,
email: initialData.email,
password: "", // Empty password means no change
+ confirmPassword: "",
role: initialData.role,
+ phone: initialData.phone,
} : {
firstName: "",
lastName: "",
email: "",
password: "",
+ confirmPassword: "",
role: "user",
+ phone: "",
},
})
@@ -77,17 +93,32 @@ export function UserForm({ initialData }: UserFormProps) {
setLoading(true)
try {
let result;
- if (initialData) {
- // Update
- result = await updateUser(initialData.id, data)
+
+ if (mode === "profile") {
+ // Profile update mode (self-service)
+ result = await updateProfile({
+ firstName: data.firstName,
+ lastName: data.lastName,
+ phone: data.phone
+ })
+ } else if (initialData?.id) {
+ // Admin update mode
+ result = await updateUser(initialData.id, {
+ firstName: data.firstName,
+ lastName: data.lastName,
+ email: data.email,
+ password: data.password,
+ role: data.role,
+ phone: data.phone
+ })
} else {
- // Create
+ // Admin create mode
if (!data.password || data.password.length < 6) {
toast.error("Yeni kullanıcı için şifre gereklidir (min 6 karakter).")
setLoading(false)
return
}
- result = await createUser(data.firstName, data.lastName, data.email, data.password, data.role)
+ result = await createUser(data.firstName, data.lastName, data.email, data.password, data.role, data.phone)
}
if (result.error) {
@@ -95,9 +126,16 @@ export function UserForm({ initialData }: UserFormProps) {
return
}
- toast.success(initialData ? "Kullanıcı güncellendi." : "Kullanıcı oluşturuldu.")
- router.push("/dashboard/users")
+ toast.success(
+ mode === "profile"
+ ? "Profil bilgileriniz güncellendi."
+ : initialData ? "Kullanıcı güncellendi." : "Kullanıcı oluşturuldu."
+ )
+
router.refresh()
+ if (mode === "admin") {
+ router.push("/dashboard/users")
+ }
} catch (error) {
toast.error("Bir sorun oluştu.")
} finally {
@@ -139,6 +177,20 @@ export function UserForm({ initialData }: UserFormProps) {
/>