This commit is contained in:
2025-12-18 00:32:45 +01:00
parent 52da147761
commit a41a72fb0d
378 changed files with 340 additions and 30813 deletions

View File

@@ -0,0 +1,48 @@
'use server';
import { createServerActionClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
export async function deleteBottle(bottleId: string) {
const supabase = createServerActionClient({ cookies });
try {
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error('Nicht autorisiert.');
}
// 1. Get bottle to check ownership and get image path
const { data: bottle, error: fetchError } = await supabase
.from('bottles')
.select('image_url, user_id')
.eq('id', bottleId)
.single();
if (fetchError || !bottle) {
throw new Error('Flasche nicht gefunden.');
}
if (bottle.user_id !== session.user.id) {
throw new Error('Keine Berechtigung.');
}
// 2. Delete bottle (Storage image cleanup could be added here, but RLS/Storage management is easier via DB trigger or manual cleanup)
const { error: deleteError } = await supabase
.from('bottles')
.delete()
.eq('id', bottleId);
if (deleteError) throw deleteError;
revalidatePath('/');
return { success: true };
} catch (error) {
console.error('Delete Bottle Error:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Fehler beim Löschen.',
};
}
}

View File

@@ -0,0 +1,33 @@
'use server';
import { createServerActionClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
export async function deleteTasting(tastingId: string, bottleId: string) {
const supabase = createServerActionClient({ cookies });
try {
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error('Nicht autorisiert.');
}
const { error: deleteError } = await supabase
.from('tastings')
.delete()
.eq('id', tastingId)
.eq('user_id', session.user.id);
if (deleteError) throw deleteError;
revalidatePath(`/bottles/${bottleId}`);
return { success: true };
} catch (error) {
console.error('Delete Tasting Error:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Fehler beim Löschen.',
};
}
}

View File

@@ -0,0 +1,46 @@
'use server';
import { createServerActionClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { BottleMetadata } from '@/types/whisky';
export async function findMatchingBottle(metadata: BottleMetadata) {
const supabase = createServerActionClient({ cookies });
try {
const { data: { session } } = await supabase.auth.getSession();
if (!session) return null;
const userId = session.user.id;
// 1. Try matching by Whiskybase ID (most reliable)
if (metadata.whiskybaseId) {
const { data: wbMatch } = await supabase
.from('bottles')
.select('id, name, distillery')
.eq('user_id', userId)
.eq('whiskybase_id', metadata.whiskybaseId)
.maybeSingle();
if (wbMatch) return wbMatch;
}
// 2. Try matching by Name and Distillery (approximate)
if (metadata.name && metadata.distillery) {
const { data: nameMatch } = await supabase
.from('bottles')
.select('id, name, distillery')
.eq('user_id', userId)
.ilike('name', metadata.name)
.ilike('distillery', metadata.distillery)
.maybeSingle();
if (nameMatch) return nameMatch;
}
return null;
} catch (error) {
console.error('Find Matching Bottle Error:', error);
return null;
}
}