90 lines
3.2 KiB
TypeScript
90 lines
3.2 KiB
TypeScript
'use server'
|
||
|
||
import { revalidatePath } from 'next/cache'
|
||
import { redirect } from 'next/navigation'
|
||
import { auth } from '@/lib/auth'
|
||
import { supabaseAdmin, deleteAuthUser } from '@/lib/supabaseAdmin'
|
||
|
||
async function requireAdmin() {
|
||
const session = await auth()
|
||
if (!session || (session.user as any)?.role !== 'ADMIN') {
|
||
throw new Error('Yetkisiz erişim')
|
||
}
|
||
}
|
||
|
||
function toIsoOrNull(dateInput: FormDataEntryValue | null): string | null {
|
||
const value = String(dateInput || '').trim()
|
||
if (!value) return null
|
||
const d = new Date(`${value}T23:59:59.999Z`)
|
||
if (isNaN(d.getTime())) return null
|
||
return d.toISOString()
|
||
}
|
||
|
||
// profiles.license_status masaüstü uygulamasının (laawos/Electron) TEK gerçek
|
||
// erişim kapısı (bkz. LicenseGate.tsx::fetchActiveStatus) ve laawos-backend'in
|
||
// API middleware'i de aynı alana bakıyor — bu yüzden bunu yazan HER yol (Kullanıcılar
|
||
// sayfası, Lisanslar sayfası) bu tek fonksiyondan geçmeli, yoksa iki ekran
|
||
// birbirinden habersiz farklı değerler yazıp "veriler eşleşmiyor" durumuna düşer.
|
||
export async function setProfileAccess(userId: string, status: string, expiresAt: string | null) {
|
||
await supabaseAdmin
|
||
.from('profiles')
|
||
.update({ license_status: status, license_expires_at: expiresAt })
|
||
.eq('id', userId)
|
||
}
|
||
|
||
export async function updateUserAction(formData: FormData) {
|
||
await requireAdmin()
|
||
|
||
const id = String(formData.get('id') || '')
|
||
if (!id) throw new Error('Kullanıcı id eksik')
|
||
|
||
const fullName = String(formData.get('full_name') || '').trim()
|
||
const barName = String(formData.get('bar_name') || '').trim()
|
||
const barNo = String(formData.get('bar_association_no') || '').trim()
|
||
const phone = String(formData.get('phone') || '').trim()
|
||
const licenseStatus = String(formData.get('license_status') || '').trim()
|
||
const licenseExpiresAt = toIsoOrNull(formData.get('license_expires_at'))
|
||
const trialEndDate = toIsoOrNull(formData.get('trial_end_date'))
|
||
|
||
const update: Record<string, unknown> = {
|
||
full_name: fullName || null,
|
||
bar_name: barName || null,
|
||
bar_association_no: barNo || null,
|
||
phone: phone || null,
|
||
trial_end_date: trialEndDate,
|
||
}
|
||
if (licenseStatus) {
|
||
// license_status + license_expires_at ikilisi setProfileAccess üzerinden yazılıyor,
|
||
// ki Lisanslar sayfasıyla aynı tek yoldan geçsin.
|
||
await setProfileAccess(id, licenseStatus, licenseExpiresAt)
|
||
} else {
|
||
update.license_expires_at = licenseExpiresAt
|
||
}
|
||
|
||
const { error } = await supabaseAdmin.from('profiles').update(update).eq('id', id)
|
||
if (error) {
|
||
redirect(`/admin/users/${id}?error=${encodeURIComponent(error.message)}`)
|
||
}
|
||
|
||
revalidatePath('/admin/users')
|
||
revalidatePath(`/admin/users/${id}`)
|
||
redirect(`/admin/users/${id}?success=1`)
|
||
}
|
||
|
||
export async function deleteUserAction(formData: FormData) {
|
||
await requireAdmin()
|
||
|
||
const id = String(formData.get('id') || '')
|
||
if (!id) throw new Error('Kullanıcı id eksik')
|
||
|
||
const { error: authError } = await deleteAuthUser(id)
|
||
if (authError) {
|
||
redirect(`/admin/users/${id}?error=${encodeURIComponent(authError)}`)
|
||
}
|
||
|
||
await supabaseAdmin.from('profiles').delete().eq('id', id)
|
||
|
||
revalidatePath('/admin/users')
|
||
redirect('/admin/users?deleted=1')
|
||
}
|