- Add NEXT_PUBLIC_SITE_URL to .env.local - Update email templates to accept siteUrl prop - Update webhook handler to pass siteUrl from env var - Update create-webhooks.graphql with placeholder URL
238 lines
5.9 KiB
TypeScript
238 lines
5.9 KiB
TypeScript
import { Button, Hr, Section, Text } from "@react-email/components";
|
|
import { BaseLayout } from "./BaseLayout";
|
|
|
|
interface OrderItem {
|
|
id: string;
|
|
name: string;
|
|
quantity: number;
|
|
price: string;
|
|
}
|
|
|
|
interface OrderCancelledProps {
|
|
language: string;
|
|
orderId: string;
|
|
orderNumber: string;
|
|
customerName: string;
|
|
items: OrderItem[];
|
|
total: string;
|
|
reason?: string;
|
|
siteUrl: string;
|
|
}
|
|
|
|
const translations: Record<
|
|
string,
|
|
{
|
|
title: string;
|
|
preview: string;
|
|
greeting: string;
|
|
orderCancelled: string;
|
|
items: string;
|
|
total: string;
|
|
reason: string;
|
|
questions: string;
|
|
}
|
|
> = {
|
|
sr: {
|
|
title: "Vaša narudžbina je otkazana",
|
|
preview: "Vaša narudžbina je otkazana",
|
|
greeting: "Poštovani {name},",
|
|
orderCancelled:
|
|
"Vaša narudžbina je otkazana. Ako niste zatražili otkazivanje, molimo kontaktirajte nas što pre.",
|
|
items: "Artikli",
|
|
total: "Ukupno",
|
|
reason: "Razlog",
|
|
questions: "Imate pitanja? Pišite nam na support@manoonoils.com",
|
|
},
|
|
en: {
|
|
title: "Your Order Has Been Cancelled",
|
|
preview: "Your order has been cancelled",
|
|
greeting: "Dear {name},",
|
|
orderCancelled:
|
|
"Your order has been cancelled. If you did not request this cancellation, please contact us as soon as possible.",
|
|
items: "Items",
|
|
total: "Total",
|
|
reason: "Reason",
|
|
questions: "Questions? Email us at support@manoonoils.com",
|
|
},
|
|
de: {
|
|
title: "Ihre Bestellung wurde storniert",
|
|
preview: "Ihre Bestellung wurde storniert",
|
|
greeting: "Sehr geehrte/r {name},",
|
|
orderCancelled:
|
|
"Ihre Bestellung wurde storniert. Wenn Sie diese Stornierung nicht angefordert haben, kontaktieren Sie uns bitte so schnell wie möglich.",
|
|
items: "Artikel",
|
|
total: "Gesamt",
|
|
reason: "Grund",
|
|
questions: "Fragen? Schreiben Sie uns an support@manoonoils.com",
|
|
},
|
|
fr: {
|
|
title: "Votre commande a été annulée",
|
|
preview: "Votre commande a été annulée",
|
|
greeting: "Cher(e) {name},",
|
|
orderCancelled:
|
|
"Votre commande a été annulée. Si vous n'avez pas demandé cette annulation, veuillez nous contacter dès que possible.",
|
|
items: "Articles",
|
|
total: "Total",
|
|
reason: "Raison",
|
|
questions: "Questions? Écrivez-nous à support@manoonoils.com",
|
|
},
|
|
};
|
|
|
|
export function OrderCancelled({
|
|
language = "en",
|
|
orderId,
|
|
orderNumber,
|
|
customerName,
|
|
items,
|
|
total,
|
|
reason,
|
|
siteUrl,
|
|
}: OrderCancelledProps) {
|
|
const t = translations[language] || translations.en;
|
|
|
|
return (
|
|
<BaseLayout previewText={t.preview} language={language} siteUrl={siteUrl}>
|
|
<Text style={styles.title}>{t.title}</Text>
|
|
<Text style={styles.greeting}>{t.greeting.replace("{name}", customerName)}</Text>
|
|
<Text style={styles.text}>{t.orderCancelled}</Text>
|
|
|
|
<Section style={styles.orderInfo}>
|
|
<Text style={styles.orderNumber}>
|
|
<strong>Order Number:</strong> {orderNumber}
|
|
</Text>
|
|
{reason && (
|
|
<Text style={styles.reason}>
|
|
<strong>{t.reason}:</strong> {reason}
|
|
</Text>
|
|
)}
|
|
</Section>
|
|
|
|
<Section style={styles.itemsSection}>
|
|
<Text style={styles.sectionTitle}>{t.items}</Text>
|
|
<Hr style={styles.hr} />
|
|
{items.map((item) => (
|
|
<Section key={item.id} style={styles.itemRow}>
|
|
<Text style={styles.itemName}>
|
|
{item.quantity}x {item.name}
|
|
</Text>
|
|
<Text style={styles.itemPrice}>{item.price}</Text>
|
|
</Section>
|
|
))}
|
|
<Hr style={styles.hr} />
|
|
<Section style={styles.totalRow}>
|
|
<Text style={styles.totalLabel}>{t.total}:</Text>
|
|
<Text style={styles.totalValue}>{total}</Text>
|
|
</Section>
|
|
</Section>
|
|
|
|
<Section style={styles.buttonSection}>
|
|
<Button href={siteUrl} style={styles.button}>
|
|
{language === "sr" ? "Pogledajte proizvode" : "Browse Products"}
|
|
</Button>
|
|
</Section>
|
|
|
|
<Text style={styles.questions}>{t.questions}</Text>
|
|
</BaseLayout>
|
|
);
|
|
}
|
|
|
|
const styles = {
|
|
title: {
|
|
fontSize: "24px",
|
|
fontWeight: "bold" as const,
|
|
color: "#dc2626",
|
|
marginBottom: "20px",
|
|
},
|
|
greeting: {
|
|
fontSize: "16px",
|
|
color: "#333333",
|
|
marginBottom: "10px",
|
|
},
|
|
text: {
|
|
fontSize: "14px",
|
|
color: "#666666",
|
|
marginBottom: "20px",
|
|
},
|
|
orderInfo: {
|
|
backgroundColor: "#fef2f2",
|
|
padding: "15px",
|
|
borderRadius: "8px",
|
|
marginBottom: "20px",
|
|
},
|
|
orderNumber: {
|
|
fontSize: "14px",
|
|
color: "#333333",
|
|
margin: "0 0 5px 0",
|
|
},
|
|
reason: {
|
|
fontSize: "14px",
|
|
color: "#991b1b",
|
|
margin: "0",
|
|
},
|
|
itemsSection: {
|
|
marginBottom: "20px",
|
|
},
|
|
sectionTitle: {
|
|
fontSize: "16px",
|
|
fontWeight: "bold" as const,
|
|
color: "#1a1a1a",
|
|
marginBottom: "10px",
|
|
},
|
|
hr: {
|
|
borderColor: "#e0e0e0",
|
|
margin: "10px 0",
|
|
},
|
|
itemRow: {
|
|
display: "flex" as const,
|
|
justifyContent: "space-between" as const,
|
|
padding: "8px 0",
|
|
},
|
|
itemName: {
|
|
fontSize: "14px",
|
|
color: "#666666",
|
|
margin: "0",
|
|
textDecoration: "line-through",
|
|
},
|
|
itemPrice: {
|
|
fontSize: "14px",
|
|
color: "#666666",
|
|
margin: "0",
|
|
textDecoration: "line-through",
|
|
},
|
|
totalRow: {
|
|
display: "flex" as const,
|
|
justifyContent: "space-between" as const,
|
|
padding: "8px 0",
|
|
},
|
|
totalLabel: {
|
|
fontSize: "16px",
|
|
fontWeight: "bold" as const,
|
|
color: "#666666",
|
|
margin: "0",
|
|
},
|
|
totalValue: {
|
|
fontSize: "16px",
|
|
fontWeight: "bold" as const,
|
|
color: "#666666",
|
|
margin: "0",
|
|
textDecoration: "line-through",
|
|
},
|
|
buttonSection: {
|
|
textAlign: "center" as const,
|
|
marginBottom: "20px",
|
|
},
|
|
button: {
|
|
backgroundColor: "#000000",
|
|
color: "#ffffff",
|
|
padding: "12px 30px",
|
|
borderRadius: "4px",
|
|
fontSize: "14px",
|
|
fontWeight: "bold" as const,
|
|
textDecoration: "none",
|
|
},
|
|
questions: {
|
|
fontSize: "14px",
|
|
color: "#666666",
|
|
},
|
|
};
|