feat: Upgrade to Next.js 16.1 & React 19.2, migrate to Supabase SSR with async client handling
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
'use server';
|
||||
|
||||
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
|
||||
import { cookies } from 'next/headers';
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
import { checkIsAdmin } from './track-api-usage';
|
||||
import { addCredits, getUserCredits } from './credit-service';
|
||||
import { AdminCreditUpdateSchema, AdminSettingsSchema } from '@/types/whisky';
|
||||
|
||||
interface UserWithCredits {
|
||||
id: string;
|
||||
@@ -23,7 +23,7 @@ interface UserWithCredits {
|
||||
*/
|
||||
export async function getAllUsersWithCredits(): Promise<UserWithCredits[]> {
|
||||
try {
|
||||
const supabase = createServerComponentClient({ cookies });
|
||||
const supabase = await createClient();
|
||||
|
||||
// Check if current user is admin
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
@@ -97,7 +97,8 @@ export async function updateUserCredits(
|
||||
reason: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const supabase = createServerComponentClient({ cookies });
|
||||
const validated = AdminCreditUpdateSchema.parse({ userId, newBalance, reason });
|
||||
const supabase = await createClient();
|
||||
|
||||
// Check if current user is admin
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
@@ -107,20 +108,20 @@ export async function updateUserCredits(
|
||||
if (!isAdmin) return { success: false, error: 'Not authorized' };
|
||||
|
||||
// Get current credits
|
||||
const currentCredits = await getUserCredits(userId);
|
||||
const currentCredits = await getUserCredits(validated.userId);
|
||||
if (!currentCredits) {
|
||||
return { success: false, error: 'User credits not found' };
|
||||
}
|
||||
|
||||
const difference = newBalance - currentCredits.balance;
|
||||
const difference = validated.newBalance - currentCredits.balance;
|
||||
|
||||
// Use addCredits which handles the transaction logging
|
||||
const result = await addCredits(userId, difference, reason, user.id);
|
||||
const result = await addCredits(validated.userId, difference, validated.reason, user.id);
|
||||
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.error('Error in updateUserCredits:', err);
|
||||
return { success: false, error: 'Failed to update credits' };
|
||||
return { success: false, error: err instanceof Error ? err.message : 'Failed to update credits' };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +133,8 @@ export async function setUserDailyLimit(
|
||||
dailyLimit: number | null
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const supabase = createServerComponentClient({ cookies });
|
||||
const validated = AdminSettingsSchema.parse({ userId, dailyLimit });
|
||||
const supabase = await createClient();
|
||||
|
||||
// Check if current user is admin
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
@@ -143,8 +145,8 @@ export async function setUserDailyLimit(
|
||||
|
||||
const { error } = await supabase
|
||||
.from('user_credits')
|
||||
.update({ daily_limit: dailyLimit })
|
||||
.eq('user_id', userId);
|
||||
.update({ daily_limit: validated.dailyLimit })
|
||||
.eq('user_id', validated.userId);
|
||||
|
||||
if (error) {
|
||||
console.error('Error setting daily limit:', error);
|
||||
@@ -154,7 +156,7 @@ export async function setUserDailyLimit(
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
console.error('Error in setUserDailyLimit:', err);
|
||||
return { success: false, error: 'Failed to set daily limit' };
|
||||
return { success: false, error: err instanceof Error ? err.message : 'Failed to set daily limit' };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +169,8 @@ export async function setUserApiCosts(
|
||||
geminiAiCost: number
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const supabase = createServerComponentClient({ cookies });
|
||||
const validated = AdminSettingsSchema.parse({ userId, googleSearchCost, geminiAiCost });
|
||||
const supabase = await createClient();
|
||||
|
||||
// Check if current user is admin
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
@@ -179,10 +182,10 @@ export async function setUserApiCosts(
|
||||
const { error } = await supabase
|
||||
.from('user_credits')
|
||||
.update({
|
||||
google_search_cost: googleSearchCost,
|
||||
gemini_ai_cost: geminiAiCost
|
||||
google_search_cost: validated.googleSearchCost,
|
||||
gemini_ai_cost: validated.geminiAiCost
|
||||
})
|
||||
.eq('user_id', userId);
|
||||
.eq('user_id', validated.userId);
|
||||
|
||||
if (error) {
|
||||
console.error('Error setting API costs:', error);
|
||||
@@ -192,7 +195,7 @@ export async function setUserApiCosts(
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
console.error('Error in setUserApiCosts:', err);
|
||||
return { success: false, error: 'Failed to set API costs' };
|
||||
return { success: false, error: err instanceof Error ? err.message : 'Failed to set API costs' };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +208,7 @@ export async function bulkAddCredits(
|
||||
reason: string
|
||||
): Promise<{ success: boolean; processed: number; failed: number; error?: string }> {
|
||||
try {
|
||||
const supabase = createServerComponentClient({ cookies });
|
||||
const supabase = await createClient();
|
||||
|
||||
// Check if current user is admin
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
|
||||
Reference in New Issue
Block a user