refactor: rename orders to inquiries and update PDF and email text

This commit is contained in:
DanielS
2026-06-30 15:23:33 +02:00
parent bdc9e6541c
commit 8f4f05a3cd
5 changed files with 57 additions and 54 deletions

View File

@@ -13,7 +13,7 @@ const defaultUrl = process.env.VERCEL_URL
export const metadata: Metadata = {
metadataBase: new URL(defaultUrl),
title: "CASPOS-Shop | Die Kasse",
description: "Konfigurieren und bestellen Sie Ihre maßgeschneiderte Business-Software in Minuten.",
description: "Konfigurieren Sie Ihre maßgeschneiderte Business-Software in Minuten und fragen Sie sie an.",
};
const geistSans = Geist({

View File

@@ -44,10 +44,10 @@ export default async function MyOrdersPage() {
<div>
<h1 className="text-3xl font-extrabold tracking-tight flex items-center gap-3">
<ShoppingBag className="w-8 h-8 text-primary" />
Meine Bestellungen
Meine Anfragen
</h1>
<p className="text-slate-400 text-sm mt-1">
Alle Ihre Bestellungen auf einen Blick inkl. aktuellem Status.
Alle Ihre Anfragen auf einen Blick inkl. aktuellem Status.
</p>
</div>
</div>
@@ -55,16 +55,16 @@ export default async function MyOrdersPage() {
{/* Fehler */}
{error && (
<div className="bg-red-500/10 border border-red-500/20 text-red-400 rounded-xl p-4 text-sm">
Fehler beim Laden der Bestellungen: {error.message}
Fehler beim Laden der Anfragen: {error.message}
</div>
)}
{/* Keine Bestellungen */}
{/* Keine Anfragen */}
{!error && (!orders || orders.length === 0) && (
<Card className="glass-dark border-white/10">
<CardContent className="flex flex-col items-center justify-center py-16 gap-4">
<Package className="w-12 h-12 text-slate-600" />
<p className="text-slate-400 text-lg">Sie haben noch keine Bestellungen aufgegeben.</p>
<p className="text-slate-400 text-lg">Sie haben noch keine Anfragen aufgegeben.</p>
<Link href="/order">
<Button>Jetzt konfigurieren</Button>
</Link>
@@ -72,7 +72,7 @@ export default async function MyOrdersPage() {
</Card>
)}
{/* Bestellliste */}
{/* Anfragenliste */}
<div className="space-y-4">
{(orders ?? []).map((order) => {
const o = order as Order
@@ -83,7 +83,7 @@ export default async function MyOrdersPage() {
{/* Kopfzeile */}
<div className="flex items-start justify-between gap-4 flex-wrap">
<div className="space-y-1">
<p className="text-xs text-slate-500 uppercase tracking-wider">Bestellnummer</p>
<p className="text-xs text-slate-500 uppercase tracking-wider">Anfragenummer</p>
<p className="font-mono font-bold text-primary text-lg">#{o.order_number}</p>
</div>
<div className="space-y-1 text-right">
@@ -136,7 +136,7 @@ export default async function MyOrdersPage() {
<>
<Button variant="ghost" size="sm" asChild className="text-xs text-slate-400 hover:text-white">
<a href={o.pdf_url} target="_blank" rel="noopener noreferrer">
<ExternalLink className="w-3 h-3 mr-1" /> Angebotsbestätigung ansehen
<ExternalLink className="w-3 h-3 mr-1" /> Anfrage ansehen
</a>
</Button>
<Button variant="ghost" size="sm" asChild className="text-xs text-slate-400 hover:text-white">

View File

@@ -50,27 +50,27 @@ export default async function OrderSuccessPage({
<CheckCircle2 className="w-12 h-12 text-green-400" />
</div>
<h1 className="text-4xl font-extrabold tracking-tight text-white">
Bestellung eingegangen!
Anfrage eingegangen!
</h1>
<p className="text-slate-400 text-lg">
Ihre Bestellung wurde erfolgreich gespeichert.
Ihre Anfrage wurde erfolgreich gespeichert.
</p>
<div className="inline-flex items-center gap-2 bg-white/5 border border-white/10 rounded-full px-5 py-2 font-mono text-lg font-bold text-primary">
#{o.order_number}
</div>
</div>
{/* Bestell-Details */}
{/* Anfrage-Details */}
<Card className="glass-dark border-white/10">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle className="text-white">Bestellübersicht</CardTitle>
<CardTitle className="text-white">Anfrageübersicht</CardTitle>
<Badge
className={
o.status === 'active'
? 'bg-green-500/20 text-green-400 border-green-500/30'
: o.status === 'cancelled'
? 'bg-red-500/20 text-red-400 border-red-500/30'
: 'bg-amber-500/20 text-amber-400 border-amber-500/30'
? 'bg-red-500/20 text-red-400 border-red-500/30'
: 'bg-amber-500/20 text-amber-400 border-amber-500/30'
}
>
{statusLabel[o.status] ?? o.status}
@@ -117,16 +117,16 @@ export default async function OrderSuccessPage({
{o.order_data.price_multiplier === 0
? "Update (0-12 Monate): 100% Rabatt (inklusive)"
: o.order_data.price_multiplier === 0.15
? "Update (13-14 Monate): 15% vom Listenpreis"
: o.order_data.price_multiplier === 0.30
? "Update (15-25 Monate): 30% vom Listenpreis"
: o.order_data.price_multiplier === 0.45
? "Update (26-37 Monate): 45% vom Listenpreis"
: o.order_data.price_multiplier === 0.60
? "Update (38-49 Monate): 60% vom Listenpreis"
: o.order_data.price_multiplier === 0.90
? "Neukauf (>= 50 Monate): 10% Rabatt"
: `Gebühr: ${o.order_data.price_multiplier * 100}%`}
? "Update (13-14 Monate): 15% vom Listenpreis"
: o.order_data.price_multiplier === 0.30
? "Update (15-25 Monate): 30% vom Listenpreis"
: o.order_data.price_multiplier === 0.45
? "Update (26-37 Monate): 45% vom Listenpreis"
: o.order_data.price_multiplier === 0.60
? "Update (38-49 Monate): 60% vom Listenpreis"
: o.order_data.price_multiplier === 0.90
? "Neukauf (>= 50 Monate): 10% Rabatt"
: `Gebühr: ${o.order_data.price_multiplier * 100}%`}
</p>
{o.order_data.last_license_date && (
<p className="text-xs font-normal text-slate-400 flex items-center gap-1">

View File

@@ -110,17 +110,17 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
<Text>Software Solutions</Text>
</View>
<View style={styles.companyInfo}>
<Text>CASPOS GmbH</Text>
<Text>Musterstraße 1</Text>
<Text>12345 Musterstadt</Text>
<Text>CASPOS Computerabrechnungssysteme GmbH</Text>
<Text>Alte Bundesstraße 16</Text>
<Text>76846 Hauenstein</Text>
<Text>Deutschland</Text>
</View>
</View>
<Text style={styles.title}>Angebotsbestätigung</Text>
<Text style={styles.title}>Anfragebestätigung</Text>
<View style={styles.section}>
<Text style={styles.label}>Besteller / Kunde</Text>
<Text style={styles.label}>Anfragender Kunde</Text>
<Text>{customer.company_name}</Text>
<Text>{customer.first_name} {customer.last_name}</Text>
<Text>{customer.address}</Text>
@@ -129,8 +129,8 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
</View>
<View style={styles.section}>
<Text style={styles.label}>Bestelldetails</Text>
<Text>Bestellnummer: {order.order_number || order.id}</Text>
<Text style={styles.label}>Anfragedetails</Text>
<Text>Anfrage-Nummer: {order.order_number || order.id}</Text>
<Text>Datum: {new Date(order.created_at || Date.now()).toLocaleDateString('de-DE')}</Text>
</View>
@@ -141,16 +141,16 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
{orderSnapshot.price_multiplier === 0
? "Update (0-12 Monate): 100% Rabatt (inklusive)"
: orderSnapshot.price_multiplier === 0.15
? "Update (13-14 Monate): 15% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.30
? "Update (15-25 Monate): 30% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.45
? "Update (26-37 Monate): 45% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.60
? "Update (38-49 Monate): 60% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.90
? "Neukauf (>= 50 Monate): 10% Rabatt auf Neukauf"
: `Gebühr: ${orderSnapshot.price_multiplier * 100}%`}
? "Update (13-14 Monate): 15% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.30
? "Update (15-25 Monate): 30% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.45
? "Update (26-37 Monate): 45% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.60
? "Update (38-49 Monate): 60% vom Listenpreis"
: orderSnapshot.price_multiplier === 0.90
? "Neukauf (>= 50 Monate): 10% Rabatt auf Neukauf"
: `Gebühr: ${orderSnapshot.price_multiplier * 100}%`}
</Text>
{orderSnapshot.last_license_date && (
<Text style={{ marginTop: 2, color: '#666' }}>
@@ -165,7 +165,7 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
<View style={styles.tableCol}><Text style={{ fontWeight: 'bold' }}>Beschreibung</Text></View>
<View style={styles.tableColPrice}><Text style={{ fontWeight: 'bold' }}>Preis (netto)</Text></View>
</View>
{items.map((item: any, idx: number) => (
<View key={idx}>
<View style={styles.tableRow}>
@@ -213,7 +213,10 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(taxAmount)}</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 5, borderTopWidth: 1, borderTopColor: '#000', paddingTop: 5 }}>
<Text style={styles.totalLabel}>Gesamtbetrag (netto):</Text>
<Text style={styles.totalLabel}>MwSt.Betrag:</Text>
<Text style={styles.totalLabel}>Gesamtbetrag (brutto):</Text>
<Text style={styles.totalLabel}>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(total)}</Text>
</View>
</View>

View File

@@ -81,7 +81,7 @@ export async function submitOrder(params: {
if (!prod) {
throw new Error(`Das ausgewählte Produkt für Kategorie "${cat.name}" wurde nicht gefunden.`)
}
// Validate selected modules
for (const mId of sel.moduleIds) {
const mod = prod.modules?.find(m => m.id === mId)
@@ -205,7 +205,7 @@ export async function submitOrder(params: {
)
// 6. PDF in Supabase Storage hochladen
const fileName = `angebotsbestaetigung_${order.id}.pdf`
const fileName = `ab_${order.id}.pdf`
const { error: uploadError } = await supabase
.storage
.from('invoices')
@@ -224,21 +224,21 @@ export async function submitOrder(params: {
try {
const formattedDate = new Date(order.created_at).toLocaleDateString('de-DE')
const formattedTotal = order.total_price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
await sendMail({
to: user.email,
subject: `Angebotsbestätigung ${orderNumber}`,
text: `Hallo,\n\nvielen Dank für Ihre Bestellung bei CASPOS Shop!\n\nBestelldetails:\n- Bestellnummer: ${orderNumber}\n- Datum: ${formattedDate}\n- Endkunde: ${customerSnapshot.company_name}\n- Gesamtsumme: ${formattedTotal}\n\nIm Anhang dieser E-Mail finden Sie Ihre Angebotsbestätigung als PDF-Dokument.\n\nViele Grüße,\nIhr CASPOS Shop-Team`,
subject: `Anfragebestätigung ${orderNumber}`,
text: `Hallo,\n\nvielen Dank für Ihre Anfrage bei CASPOS Shop!\n\nAngebotsdetails:\n- Anfrage-Nummer: ${orderNumber}\n- Datum: ${formattedDate}\n- Endkunde: ${customerSnapshot.company_name}\n- Gesamtsumme: ${formattedTotal}\n\nIm Anhang dieser E-Mail finden Sie Ihre Anfragebestätigung als PDF-Dokument.\n\nViele Grüße,\nIhr CASPOS Shop-Team`,
html: `
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e2e8f0; border-radius: 8px;">
<h2 style="color: #0f172a; margin-bottom: 16px;">Vielen Dank für Ihre Bestellung!</h2>
<h2 style="color: #0f172a; margin-bottom: 16px;">Vielen Dank für Ihre Anfrage!</h2>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">Hallo,</p>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">wir freuen uns sehr über Ihre Bestellung bei CASPOS Shop. Ihre Bestellung wurde erfolgreich entgegengenommen und wird nun verarbeitet.</p>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">wir freuen uns sehr über Ihre Anfrage bei CASPOS Shop. Ihre Anfrage wurde erfolgreich entgegengenommen und wird nun verarbeitet.</p>
<div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; padding: 16px; margin: 24px 0;">
<h3 style="color: #0f172a; margin-top: 0; margin-bottom: 12px;">Bestelldetails</h3>
<h3 style="color: #0f172a; margin-top: 0; margin-bottom: 12px;">Anfrage-Details</h3>
<table style="width: 100%; border-collapse: collapse; font-size: 14px; color: #475569;">
<tr>
<td style="padding: 4px 0; font-weight: bold; width: 140px;">Bestellnummer:</td>
<td style="padding: 4px 0; font-weight: bold; width: 140px;">Anfrage-Nummer:</td>
<td style="padding: 4px 0;">${orderNumber}</td>
</tr>
<tr>
@@ -255,7 +255,7 @@ export async function submitOrder(params: {
</tr>
</table>
</div>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">Im Anhang dieser E-Mail finden Sie Ihre Angebotsbestätigung als PDF-Dokument.</p>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">Im Anhang dieser E-Mail finden Sie Ihre Anfragebestätigung als PDF-Dokument.</p>
<p style="color: #475569; font-size: 16px; line-height: 1.5; margin-top: 24px;">Mit freundlichen Grüßen,<br>Ihr CASPOS Shop-Team</p>
<hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 24px 0;">
<p style="color: #94a3b8; font-size: 12px; text-align: center;">Diese E-Mail wurde automatisch generiert. Bitte antworten Sie nicht darauf.</p>
@@ -321,7 +321,7 @@ export async function updateOrderStatus(
if (order.user_id) {
try {
const { data: { user }, error: userError } = await admin.auth.admin.getUserById(order.user_id)
if (!userError && user && user.email) {
const orderNumber = order.order_number || order.id.slice(0, 8)
const statusLabelMap: Record<string, string> = {