refactor(wording): change 'Angebot' to 'Anfrage' in client views and order emails

This commit is contained in:
DanielS
2026-07-03 14:55:56 +02:00
parent 5c28fbdea5
commit 23be8bcb52
6 changed files with 31 additions and 32 deletions

View File

@@ -8,7 +8,7 @@ export default async function AdminOrdersPage() {
<div className="flex justify-between items-center">
<div>
<h1 className="text-3xl font-bold tracking-tight text-gradient">Bestellungen</h1>
<p className="text-slate-400">Verwalten Sie alle Kundenbestellungen und greifen Sie auf generierte Angebotsbestätigungen zu.</p>
<p className="text-slate-400">Verwalten Sie alle Kundenbestellungen und greifen Sie auf generierte Annfragesbestätigungen zu.</p>
</div>
</div>
@@ -21,7 +21,7 @@ export default async function AdminOrdersPage() {
async function OrdersData() {
const adminDb = createAdminClient()
const { data: orders, error } = await adminDb
.from('orders')
.select('*')

View File

@@ -78,12 +78,12 @@ export default function Impressum() {
<h2 className="text-xl font-bold text-white">Haftungsausschluss</h2>
<section className="space-y-2">
<h3 className="text-md font-semibold text-slate-200">1. Inhalt des Onlineangebotes</h3>
<h3 className="text-md font-semibold text-slate-200">1. Inhalt der Onlineanfrage</h3>
<p className="text-sm text-slate-400 leading-relaxed">
Der Autor übernimmt keinerlei Gewähr für die Aktualität, Korrektheit, Vollständigkeit oder Qualität der bereitgestellten Informationen. Haftungsansprüche gegen den Autor, welche sich auf Schäden materieller oder ideeller Art beziehen, die durch die Nutzung oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung fehlerhafter und unvollständiger Informationen verursacht wurden, sind grundsätzlich ausgeschlossen, sofern seitens des Autors kein nachweislich vorsätzliches oder grob fahrlässiges Verschulden vorliegt.
</p>
<p className="text-sm text-slate-400 leading-relaxed">
Alle Angebote sind freibleibend und unverbindlich. Der Autor behält es sich ausdrücklich vor, Teile der Seiten oder das gesamte Angebot ohne gesonderte Ankündigung zu verändern, zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.
Alle Anfragen sind freibleibend und unverbindlich. Der Autor behält es sich ausdrücklich vor, Teile der Seiten oder die gesamte Anfrage ohne gesonderte Ankündigung zu verändern, zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.
</p>
</section>
@@ -93,14 +93,14 @@ export default function Impressum() {
Bei direkten oder indirekten Verweisen auf fremde Webseiten (Hyperlinks), die außerhalb des Verantwortungsbereiches des Autors liegen, würde eine Haftungsverpflichtung ausschließlich in dem Fall in Kraft treten, in dem der Autor von den Inhalten Kenntnis hat und es ihm technisch möglich und zumutbar wäre, die Nutzung im Falle rechtswidriger Inhalte zu verhindern. Der Autor erklärt hiermit ausdrücklich, dass zum Zeitpunkt der Linksetzung keine illegalen Inhalte auf den zu verlinkenden Seiten erkennbar waren.
</p>
<p className="text-sm text-slate-400 leading-relaxed">
Auf die aktuelle und zukünftige Gestaltung, die Inhalte oder die Urheberschaft der gelinkten/verknüpften Seiten hat der Autor keinerlei Einfluss. Deshalb distanziert er sich hiermit ausdrücklich von allen Inhalten aller gelinkten /verknüpften Seiten, die nach der Linksetzung verändert wurden. Diese Feststellung gilt für alle innerhalb des eigenen Internetangebotes gesetzten Links und Verweise sowie für Fremdeinträge in vom Autor eingerichteten Gästebüchern, Diskussionsforen und Mailinglisten. Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, haftet allein der Anbieter der Seite, auf welche verwiesen wurde, nicht derjenige, der über Links auf die jeweilige Veröffentlichung lediglich verweist.
Auf die aktuelle und zukünftige Gestaltung, die Inhalte oder die Urheberschaft der gelinkten/verknüpften Seiten hat der Autor keinerlei Einfluss. Deshalb distanziert er sich hiermit ausdrücklich von allen Inhalten aller gelinkten /verknüpften Seiten, die nach der Linksetzung verändert wurden. Diese Feststellung gilt für alle innerhalb des eigenen Internetanfrage gesetzten Links und Verweise sowie für Fremdeinträge in vom Autor eingerichteten Gästebüchern, Diskussionsforen und Mailinglisten. Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, haftet allein der Anbieter der Seite, auf welche verwiesen wurde, nicht derjenige, der über Links auf die jeweilige Veröffentlichung lediglich verweist.
</p>
</section>
<section className="space-y-2">
<h3 className="text-md font-semibold text-slate-200">4. Rechtswirksamkeit dieses Haftungsausschlusses</h3>
<p className="text-sm text-slate-400 leading-relaxed">
Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese Seite verwiesen wurde. Sofern Teile oder einzelne Formulierungen dieses Textes der geltenden Rechtslage nicht, nicht mehr oder nicht vollständig entsprechen sollten, bleiben die übrigen Teile des Dokumentes in ihrem Inhalt und ihrer Gültigkeit davon unberührt.
Dieser Haftungsausschluss ist als Teil der Onlineanfrage zu betrachten, von dem aus auf diese Seite verwiesen wurde. Sofern Teile oder einzelne Formulierungen dieses Textes der geltenden Rechtslage nicht, nicht mehr oder nicht vollständig entsprechen sollten, bleiben die übrigen Teile des Dokumentes in ihrem Inhalt und ihrer Gültigkeit davon unberührt.
</p>
</section>
</div>

View File

@@ -209,7 +209,7 @@ export default async function OrderSuccessPage({
<div className="flex gap-2 pt-2">
<Button variant="outline" size="sm" asChild className="border-white/10 hover:bg-white/10">
<a href={resolveSupabaseUrl(o.pdf_url)} target="_blank" rel="noopener noreferrer">
<ExternalLink className="w-4 h-4 mr-2" /> Angebotsbestätigung ansehen
<ExternalLink className="w-4 h-4 mr-2" /> Anfragebestätigung ansehen
</a>
</Button>
<Button variant="secondary" size="sm" asChild>

View File

@@ -118,9 +118,8 @@ export function SetupWizard() {
{[1, 2, 3].map((s) => (
<div
key={s}
className={`h-1.5 rounded-full transition-all duration-300 ${
s === step ? 'w-8 bg-blue-500' : 'w-2 bg-slate-800'
}`}
className={`h-1.5 rounded-full transition-all duration-300 ${s === step ? 'w-8 bg-blue-500' : 'w-2 bg-slate-800'
}`}
/>
))}
</div>
@@ -143,7 +142,7 @@ export function SetupWizard() {
<div className="text-center space-y-2">
<h1 className="text-3xl font-extrabold tracking-tight">Willkommen bei CASPOS!</h1>
<p className="text-slate-400 leading-relaxed">
Richten Sie Ihren persönlichen Lizenz- und Angebots-Shop in wenigen Schritten ein. Wir konfigurieren Ihr Administrator-Konto und die Mailverbindung.
Richten Sie Ihren persönlichen Lizenz- und Anfrage-Shop in wenigen Schritten ein. Wir konfigurieren Ihr Administrator-Konto und die Mailverbindung.
</p>
</div>
@@ -158,7 +157,7 @@ export function SetupWizard() {
</div>
<div className="flex items-center gap-2">
<Check className="w-4 h-4 text-green-400 shrink-0" />
<span>SMTP Mailversand für direkte Angebotsbestätigungen</span>
<span>SMTP Mailversand für direkte Anfragebestätigungen</span>
</div>
</div>

View File

@@ -431,7 +431,7 @@ export function OrderWizard({
router.push(`/order/success?id=${order.id}`)
} catch (error: any) {
console.error(error)
alert(error?.message || (initialOrder ? 'Fehler beim Aktualisieren des Angebots.' : 'Fehler bei der Bestellung. Bitte versuchen Sie es erneut.'))
alert(error?.message || (initialOrder ? 'Fehler beim Aktualisieren der Anfrage.' : 'Fehler bei der Bestellung. Bitte versuchen Sie es erneut.'))
setIsSubmitting(false) // Nur bei Fehler wieder entsperren
}
}
@@ -447,8 +447,8 @@ export function OrderWizard({
<div key={s} className="relative z-10 flex flex-col items-center gap-2">
<div
className={`w-10 h-10 rounded-full flex items-center justify-center transition-all duration-500 ${step >= s
? 'bg-primary text-white scale-110 shadow-[0_0_15px_rgba(59,130,246,0.5)]'
: 'bg-slate-800 text-slate-400'
? 'bg-primary text-white scale-110 shadow-[0_0_15px_rgba(59,130,246,0.5)]'
: 'bg-slate-800 text-slate-400'
}`}
>
{step > s ? <Check className="w-6 h-6" /> : s}
@@ -534,8 +534,8 @@ export function OrderWizard({
<label
key={customer.id}
className={`flex items-start p-4 rounded-xl border-2 cursor-pointer transition-all ${selectedEndCustomerId === customer.id
? 'border-primary bg-primary/5'
: 'border-white/5 bg-white/5 hover:bg-white/10'
? 'border-primary bg-primary/5'
: 'border-white/5 bg-white/5 hover:bg-white/10'
}`}
>
<input
@@ -648,8 +648,8 @@ export function OrderWizard({
<div
onClick={() => handleBillingIntervalChange('one_time')}
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${selectedBillingInterval === 'one_time'
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
: 'border-white/5 bg-white/5 hover:border-white/20'
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
: 'border-white/5 bg-white/5 hover:border-white/20'
}`}
>
<div>
@@ -674,8 +674,8 @@ export function OrderWizard({
<div
onClick={() => handleBillingIntervalChange('monthly')}
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${selectedBillingInterval === 'monthly'
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
: 'border-white/5 bg-white/5 hover:border-white/20'
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
: 'border-white/5 bg-white/5 hover:border-white/20'
}`}
>
<div>
@@ -1271,12 +1271,12 @@ export function OrderWizard({
>
{isSubmitting ? (
initialOrder ? (
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Angebot wird aktualisiert...</>
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Anfrage wird aktualisiert...</>
) : (
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Anfrage wird versendet...</>
)
) : (
initialOrder ? 'Angebot aktualisieren' : 'Anfrage versenden'
initialOrder ? 'Anfrage aktualisieren' : 'Anfrage versenden'
)}
</Button>
<Button variant="ghost" className="w-full text-white" onClick={prevStep}>

View File

@@ -315,7 +315,7 @@ export async function submitOrder(params: {
await sendMail({
to: user.email,
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${totalDetailsText}\n\nIm Anhang dieser E-Mail finden Sie Ihre Anfragebestätigung als PDF-Dokument.\n\nViele Grüße,\nIhr CASPOS Shop-Team`,
text: `Hallo,\n\nvielen Dank für Ihre Anfrage bei CASPOS Shop!\n\nAnfragedetails:\n- Anfrage-Nummer: ${orderNumber}\n- Datum: ${formattedDate}\n- Endkunde: ${customerSnapshot.company_name}\n${totalDetailsText}\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 Anfrage!</h2>
@@ -347,7 +347,7 @@ export async function submitOrder(params: {
`,
attachments: [
{
filename: `Angebotsbestaetigung_${orderNumber}.pdf`,
filename: `Anfragebestaetigung_${orderNumber}.pdf`,
content: buffer,
contentType: 'application/pdf',
}
@@ -499,11 +499,11 @@ export async function updateOrder(
const isOwner = existingOrder.user_id === user.id
if (!isAdmin && !isOwner) {
throw new Error('Keine Berechtigung dieses Angebot zu bearbeiten.')
throw new Error('Keine Berechtigung dieses Anfrage zu bearbeiten.')
}
if (existingOrder.status === 'completed' && !isAdmin) {
throw new Error('Abgeschlossene Angebote können nicht mehr bearbeitet werden.')
throw new Error('Abgeschlossene Anfragen können nicht mehr bearbeitet werden.')
}
// Fetch catalog directly from DB to prevent client tampering
@@ -720,13 +720,13 @@ export async function updateOrder(
await sendMail({
to: orderUserEmail,
subject: `Angebotsänderung ${order.order_number}`,
text: `Hallo,\n\nihr Angebot wurde erfolgreich aktualisiert!\n\nNeue Angebotsdetails:\n- Anfrage-Nummer: ${order.order_number}\n- Datum: ${formattedDate}\n- Endkunde: ${customerSnapshot.company_name}\n${totalDetailsText}\n\nIm Anhang dieser E-Mail finden Sie Ihr aktualisiertes Angebot als PDF-Dokument.\n\nViele Grüße,\nIhr CASPOS Shop-Team`,
subject: `Anfrageänderung ${order.order_number}`,
text: `Hallo,\n\nihre Anfrage wurde erfolgreich aktualisiert!\n\nNeue Anfragedetails:\n- Anfrage-Nummer: ${order.order_number}\n- Datum: ${formattedDate}\n- Endkunde: ${customerSnapshot.company_name}\n${totalDetailsText}\n\nIm Anhang dieser E-Mail finden Sie Ihre aktualisierte Anfrage 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;">Ihr Angebot wurde aktualisiert!</h2>
<h2 style="color: #0f172a; margin-bottom: 16px;">Ihre Anfrage wurde aktualisiert!</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;">Ihr Angebot mit der Nummer ${order.order_number} wurde erfolgreich aktualisiert.</p>
<p style="color: #475569; font-size: 16px; line-height: 1.5;">Ihr Anfrage mit der Nummer ${order.order_number} wurde erfolgreich aktualisiert.</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;">Neue Anfrage-Details</h3>
<table style="width: 100%; border-collapse: collapse; font-size: 14px; color: #475569;">
@@ -751,7 +751,7 @@ export async function updateOrder(
`,
attachments: [
{
filename: `Angebotsbestaetigung_${order.order_number}.pdf`,
filename: `Anfragebestaetigung_${order.order_number}.pdf`,
content: buffer,
contentType: 'application/pdf',
}