467 lines
12 KiB
TypeScript
467 lines
12 KiB
TypeScript
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
|
import { createBrowserClient } from "@supabase/ssr";
|
|
|
|
export type SupabaseServiceClient = SupabaseClient<Database>;
|
|
|
|
export interface Database {
|
|
public: {
|
|
Tables: {
|
|
email_queue: {
|
|
Row: {
|
|
id: string;
|
|
mail_from: string;
|
|
mail_to: string;
|
|
reply_to: string | null;
|
|
subject: string;
|
|
html: string;
|
|
body_text: string;
|
|
status: string;
|
|
retry_count: number;
|
|
next_retry_at: string;
|
|
error_last: string | null;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
mail_from: string;
|
|
mail_to: string;
|
|
reply_to?: string | null;
|
|
subject: string;
|
|
html: string;
|
|
body_text: string;
|
|
status?: string;
|
|
retry_count?: number;
|
|
next_retry_at?: string;
|
|
error_last?: string | null;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
status?: string;
|
|
retry_count?: number;
|
|
next_retry_at?: string;
|
|
error_last?: string | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
admin_users: {
|
|
Row: {
|
|
id: string;
|
|
email: string;
|
|
name: string | null;
|
|
password_hash: string;
|
|
aktiv: boolean;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
email: string;
|
|
name?: string | null;
|
|
password_hash: string;
|
|
aktiv?: boolean;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
email?: string;
|
|
name?: string | null;
|
|
password_hash?: string;
|
|
aktiv?: boolean;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
admin_audit_logs: {
|
|
Row: {
|
|
id: string;
|
|
email: string;
|
|
ip_addr: string;
|
|
user_agent: string;
|
|
success: boolean;
|
|
reason: string | null;
|
|
timestamp: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
email: string;
|
|
ip_addr: string;
|
|
user_agent: string;
|
|
success: boolean;
|
|
reason?: string | null;
|
|
timestamp?: string;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
admin_session_blacklist: {
|
|
Row: {
|
|
id: string;
|
|
admin_id: string;
|
|
token_signature: string;
|
|
revoked_at: string;
|
|
reason: string;
|
|
notes: string | null;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
admin_id: string;
|
|
token_signature: string;
|
|
revoked_at?: string;
|
|
reason: string;
|
|
notes?: string | null;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
action_token_blacklist: {
|
|
Row: {
|
|
id: string;
|
|
anfrage_id: string;
|
|
token_signature: string;
|
|
action_type: string;
|
|
used_at: string;
|
|
used_by_ip: string | null;
|
|
notes: string | null;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
anfrage_id: string;
|
|
token_signature: string;
|
|
action_type: string;
|
|
used_at?: string;
|
|
used_by_ip?: string | null;
|
|
notes?: string | null;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
page_views: {
|
|
Row: {
|
|
id: string;
|
|
path: string;
|
|
timestamp: string;
|
|
ip_anon: string | null;
|
|
device_type: string | null;
|
|
browser: string | null;
|
|
os: string | null;
|
|
referrer: string | null;
|
|
session_id: string;
|
|
duration_ms: number | null;
|
|
is_bot: boolean;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
path: string;
|
|
timestamp?: string;
|
|
ip_anon?: string | null;
|
|
device_type?: string | null;
|
|
browser?: string | null;
|
|
os?: string | null;
|
|
referrer?: string | null;
|
|
session_id: string;
|
|
duration_ms?: number | null;
|
|
is_bot?: boolean;
|
|
};
|
|
Update: {
|
|
duration_ms?: number | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
phone_clicks: {
|
|
Row: {
|
|
id: number;
|
|
phone_number: string;
|
|
source_page: string;
|
|
source_element: string;
|
|
session_id: string | null;
|
|
ip_anonymized: string | null;
|
|
device_type: string | null;
|
|
browser: string | null;
|
|
os: string | null;
|
|
timestamp: string;
|
|
};
|
|
Insert: {
|
|
phone_number: string;
|
|
source_page: string;
|
|
source_element: string;
|
|
session_id?: string | null;
|
|
ip_anonymized?: string | null;
|
|
device_type?: string | null;
|
|
browser?: string | null;
|
|
os?: string | null;
|
|
timestamp?: string;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
anfragen: {
|
|
Row: {
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
betreff: string;
|
|
nachricht: string | null;
|
|
status: string;
|
|
admin_notizen: string | null;
|
|
kunde_id: string | null;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
name: string;
|
|
email: string;
|
|
betreff: string;
|
|
nachricht?: string | null;
|
|
status?: string;
|
|
admin_notizen?: string | null;
|
|
kunde_id?: string | null;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
status?: string;
|
|
admin_notizen?: string | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
hero_content: {
|
|
Row: {
|
|
id: string;
|
|
site_name: string;
|
|
site_tagline: string;
|
|
logo_path: string | null;
|
|
favicon_path: string | null;
|
|
eyebrow_text: string;
|
|
headline1: string;
|
|
headline2: string;
|
|
subtext1: string;
|
|
subtext2: string;
|
|
cta1_text: string;
|
|
cta1_href: string;
|
|
cta2_text: string;
|
|
cta2_href: string;
|
|
bg_image_path: string | null;
|
|
updated_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
site_name?: string;
|
|
site_tagline?: string;
|
|
logo_path?: string | null;
|
|
favicon_path?: string | null;
|
|
eyebrow_text?: string;
|
|
headline1?: string;
|
|
headline2?: string;
|
|
subtext1?: string;
|
|
subtext2?: string;
|
|
cta1_text?: string;
|
|
cta1_href?: string;
|
|
cta2_text?: string;
|
|
cta2_href?: string;
|
|
bg_image_path?: string | null;
|
|
updated_at?: string;
|
|
};
|
|
Update: {
|
|
site_name?: string;
|
|
site_tagline?: string;
|
|
logo_path?: string | null;
|
|
favicon_path?: string | null;
|
|
eyebrow_text?: string;
|
|
headline1?: string;
|
|
headline2?: string;
|
|
subtext1?: string;
|
|
subtext2?: string;
|
|
cta1_text?: string;
|
|
cta1_href?: string;
|
|
cta2_text?: string;
|
|
cta2_href?: string;
|
|
bg_image_path?: string | null;
|
|
updated_at?: string;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
hero_badges: {
|
|
Row: {
|
|
id: string;
|
|
text: string;
|
|
reihenfolge: number;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
text: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Update: {
|
|
text?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
ueber_uns_content: {
|
|
Row: {
|
|
id: string;
|
|
eyebrow_text: string;
|
|
absatz1: string;
|
|
absatz2: string;
|
|
bild_url: string | null;
|
|
updated_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
eyebrow_text?: string;
|
|
absatz1?: string;
|
|
absatz2?: string;
|
|
bild_url?: string | null;
|
|
updated_at?: string;
|
|
};
|
|
Update: {
|
|
eyebrow_text?: string;
|
|
absatz1?: string;
|
|
absatz2?: string;
|
|
bild_url?: string | null;
|
|
updated_at?: string;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
ueber_uns_stats: {
|
|
Row: {
|
|
id: string;
|
|
wert: string;
|
|
label: string;
|
|
reihenfolge: number;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
wert: string;
|
|
label: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Update: {
|
|
wert?: string;
|
|
label?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
galerie_bilder: {
|
|
Row: {
|
|
id: string;
|
|
storage_path: string;
|
|
alt_text: string;
|
|
reihenfolge: number;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
storage_path: string;
|
|
alt_text?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Update: {
|
|
storage_path?: string;
|
|
alt_text?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
kontakt_info: {
|
|
Row: {
|
|
id: string;
|
|
telefon: string;
|
|
email: string;
|
|
adresse_zeile1: string;
|
|
adresse_zeile2: string;
|
|
formular_empfaenger: string;
|
|
updated_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
telefon?: string;
|
|
email?: string;
|
|
adresse_zeile1?: string;
|
|
adresse_zeile2?: string;
|
|
formular_empfaenger?: string;
|
|
updated_at?: string;
|
|
};
|
|
Update: {
|
|
telefon?: string;
|
|
email?: string;
|
|
adresse_zeile1?: string;
|
|
adresse_zeile2?: string;
|
|
formular_empfaenger?: string;
|
|
updated_at?: string;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
kontakt_oeffnungszeiten: {
|
|
Row: {
|
|
id: string;
|
|
tag: string;
|
|
von: string;
|
|
bis: string;
|
|
reihenfolge: number;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
tag: string;
|
|
von: string;
|
|
bis: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Update: {
|
|
tag?: string;
|
|
von?: string;
|
|
bis?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
kontakt_social: {
|
|
Row: {
|
|
id: string;
|
|
platform: string;
|
|
url: string;
|
|
reihenfolge: number;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
platform: string;
|
|
url: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Update: {
|
|
platform?: string;
|
|
url?: string;
|
|
reihenfolge?: number;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
};
|
|
Views: Record<string, never>;
|
|
Functions: Record<string, never>;
|
|
Enums: Record<string, never>;
|
|
CompositeTypes: Record<string, never>;
|
|
};
|
|
}
|
|
|
|
let serviceClient: SupabaseServiceClient | null = null;
|
|
|
|
export function createServiceClient(): SupabaseServiceClient {
|
|
if (serviceClient) return serviceClient;
|
|
|
|
const url = process.env.SUPABASE_URL;
|
|
const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
|
|
if (!url || !key) {
|
|
throw new Error("SUPABASE_URL oder SUPABASE_SERVICE_ROLE_KEY fehlt in .env.local");
|
|
}
|
|
|
|
serviceClient = createClient<Database>(url, key, {
|
|
auth: { persistSession: false },
|
|
});
|
|
|
|
return serviceClient;
|
|
}
|
|
|
|
export function createBrowserSupabaseClient() {
|
|
return createBrowserClient<Database>(
|
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
);
|
|
}
|