From b537ca50cf868e6083a3100030b780f39fafa214 Mon Sep 17 00:00:00 2001 From: DanielS Date: Thu, 25 Jun 2026 02:29:33 +0200 Subject: [PATCH] feat: Add email field to end_customers table and UI screens --- .../admin/companies/[id]/customers/page.tsx | 22 ++++++++++++++++++- shop/app/my-customers/[id]/page.tsx | 4 +++- shop/app/my-customers/new/page.tsx | 3 ++- shop/lib/actions/companies.ts | 4 ++++ shop/lib/actions/end-customers.ts | 4 ++++ shop/lib/types.ts | 1 + ...60625001000_add_email_to_end_customers.sql | 3 +++ 7 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 shop/supabase/migrations/20260625001000_add_email_to_end_customers.sql diff --git a/shop/app/admin/companies/[id]/customers/page.tsx b/shop/app/admin/companies/[id]/customers/page.tsx index 6e22880..bce0fb5 100644 --- a/shop/app/admin/companies/[id]/customers/page.tsx +++ b/shop/app/admin/companies/[id]/customers/page.tsx @@ -62,6 +62,7 @@ export default function CompanyCustomersPage() { const [city, setCity] = useState('') const [vatId, setVatId] = useState('') const [partnerId, setPartnerId] = useState('') + const [email, setEmail] = useState('') const [error, setError] = useState(null) const loadData = async () => { @@ -98,6 +99,7 @@ export default function CompanyCustomersPage() { setCity(customer ? customer.city || '' : '') setVatId(customer ? customer.vat_id || '' : '') setPartnerId(customer ? customer.partner_id || '' : (partners.length > 0 ? partners[0].id : '')) + setEmail(customer ? customer.email || '' : '') setError(null) setIsOpen(true) } @@ -120,6 +122,7 @@ export default function CompanyCustomersPage() { zip: zip.trim() || undefined, city: city.trim() || undefined, vat_id: vatId.trim() || undefined, + email: email.trim() || undefined, } if (editingCustomer) { @@ -155,7 +158,8 @@ export default function CompanyCustomersPage() { const personMatch = `${c.first_name || ''} ${c.last_name || ''}`.toLowerCase().includes(q) const addressMatch = `${c.street || ''} ${c.zip || ''} ${c.city || ''}`.toLowerCase().includes(q) const partnerMatch = c.partner_name?.toLowerCase().includes(q) - return nameMatch || personMatch || addressMatch || partnerMatch + const emailMatch = c.email?.toLowerCase().includes(q) + return nameMatch || personMatch || addressMatch || partnerMatch || emailMatch }) @@ -237,6 +241,7 @@ export default function CompanyCustomersPage() { Endkunde (Firma / Kontakt) Lieferadresse + E-Mail USt-ID Zugeordneter Partner Aktionen @@ -268,6 +273,9 @@ export default function CompanyCustomersPage() { )} + + {customer.email || } + {customer.vat_id || } @@ -425,6 +433,18 @@ export default function CompanyCustomersPage() { +
+ + setEmail(e.target.value)} + className="bg-slate-50 dark:bg-white/5 border-slate-200 dark:border-white/10" + /> +
+ {error && (

{error}

)} diff --git a/shop/app/my-customers/[id]/page.tsx b/shop/app/my-customers/[id]/page.tsx index b93eae9..7bab62a 100644 --- a/shop/app/my-customers/[id]/page.tsx +++ b/shop/app/my-customers/[id]/page.tsx @@ -21,7 +21,7 @@ export default function CustomerDetailPage({ params }: { params: Promise<{ id: s const [anonymizing, setAnonymizing] = useState(false) const [showGdprConfirm, setShowGdprConfirm] = useState(false) const [form, setForm] = useState({ - company_name: '', vat_id: '', first_name: '', last_name: '', street: '', zip: '', city: '', + company_name: '', vat_id: '', first_name: '', last_name: '', street: '', zip: '', city: '', email: '', }) useEffect(() => { @@ -37,6 +37,7 @@ export default function CustomerDetailPage({ params }: { params: Promise<{ id: s street: c.street ?? '', zip: c.zip ?? '', city: c.city ?? '', + email: c.email ?? '', }) setLoading(false) }) @@ -121,6 +122,7 @@ export default function CustomerDetailPage({ params }: { params: Promise<{ id: s { label: 'USt-IdNr.', key: 'vat_id', span: false }, { label: 'Vorname', key: 'first_name', span: false }, { label: 'Nachname', key: 'last_name', span: false }, + { label: 'E-Mail', key: 'email', span: true }, { label: 'Straße & Hausnummer', key: 'street', span: true }, { label: 'PLZ', key: 'zip', span: false }, { label: 'Ort', key: 'city', span: false }, diff --git a/shop/app/my-customers/new/page.tsx b/shop/app/my-customers/new/page.tsx index abd6c9d..c8ad134 100644 --- a/shop/app/my-customers/new/page.tsx +++ b/shop/app/my-customers/new/page.tsx @@ -14,7 +14,7 @@ export default function NewCustomerPage() { const router = useRouter() const [saving, setSaving] = useState(false) const [form, setForm] = useState({ - company_name: '', vat_id: '', first_name: '', last_name: '', street: '', zip: '', city: '', + company_name: '', vat_id: '', first_name: '', last_name: '', street: '', zip: '', city: '', email: '', }) const handleSave = async () => { @@ -58,6 +58,7 @@ export default function NewCustomerPage() { { label: 'USt-IdNr.', key: 'vat_id', span: false, placeholder: 'DE123456789' }, { label: 'Vorname', key: 'first_name', span: false, placeholder: '' }, { label: 'Nachname', key: 'last_name', span: false, placeholder: '' }, + { label: 'E-Mail', key: 'email', span: true, placeholder: 'kunde@beispiel.de' }, { label: 'Straße & Hausnummer', key: 'street', span: true, placeholder: 'Musterstraße 1' }, { label: 'PLZ', key: 'zip', span: false, placeholder: '12345' }, { label: 'Ort', key: 'city', span: false, placeholder: 'Musterstadt' }, diff --git a/shop/lib/actions/companies.ts b/shop/lib/actions/companies.ts index 4001c1b..85f366f 100644 --- a/shop/lib/actions/companies.ts +++ b/shop/lib/actions/companies.ts @@ -169,6 +169,7 @@ export async function adminCreateEndCustomer(data: { street?: string zip?: string city?: string + email?: string }) { const admin = createAdminClient() const { data: dbData, error } = await admin @@ -182,6 +183,7 @@ export async function adminCreateEndCustomer(data: { street: data.street || null, zip: data.zip || null, city: data.city || null, + email: data.email || null, }]) .select() .single() @@ -198,6 +200,7 @@ export async function adminUpdateEndCustomer(id: string, data: { street?: string zip?: string city?: string + email?: string }) { const admin = createAdminClient() const { data: dbData, error } = await admin @@ -211,6 +214,7 @@ export async function adminUpdateEndCustomer(id: string, data: { street: data.street || null, zip: data.zip || null, city: data.city || null, + email: data.email || null, }) .eq('id', id) .select() diff --git a/shop/lib/actions/end-customers.ts b/shop/lib/actions/end-customers.ts index 1c6d152..26d0263 100644 --- a/shop/lib/actions/end-customers.ts +++ b/shop/lib/actions/end-customers.ts @@ -15,6 +15,7 @@ export type EndCustomerFormData = { street?: string zip?: string city?: string + email?: string } // ─── Lesen ─────────────────────────────────────────────────────────────────── @@ -72,6 +73,7 @@ export async function createEndCustomer(formData: EndCustomerFormData): Promise< street: formData.street || null, zip: formData.zip || null, city: formData.city || null, + email: formData.email || null, }]) .select() .single() @@ -101,6 +103,7 @@ export async function updateEndCustomer(id: string, formData: EndCustomerFormDat street: formData.street || null, zip: formData.zip || null, city: formData.city || null, + email: formData.email || null, }) .eq('id', id) @@ -134,6 +137,7 @@ export async function anonymizeEndCustomer(id: string): Promise { street: null, zip: null, city: null, + email: null, is_anonymized: true, }) .eq('id', id) diff --git a/shop/lib/types.ts b/shop/lib/types.ts index cc1f7db..a36499a 100644 --- a/shop/lib/types.ts +++ b/shop/lib/types.ts @@ -62,6 +62,7 @@ export type EndCustomer = { street: string | null zip: string | null city: string | null + email?: string | null is_anonymized: boolean created_at: string } diff --git a/shop/supabase/migrations/20260625001000_add_email_to_end_customers.sql b/shop/supabase/migrations/20260625001000_add_email_to_end_customers.sql new file mode 100644 index 0000000..91e9cbe --- /dev/null +++ b/shop/supabase/migrations/20260625001000_add_email_to_end_customers.sql @@ -0,0 +1,3 @@ +-- Migration: Add email column to end_customers table +ALTER TABLE public.end_customers + ADD COLUMN IF NOT EXISTS email TEXT;