fix(competitor-analysis): final migration fixes and documentation updates

This commit is contained in:
2026-05-15 20:43:35 +00:00
parent ec0a977211
commit eec9b38af5
3 changed files with 95 additions and 4 deletions

View File

@@ -150,8 +150,8 @@ function App() {
// Email States
const [reminderResult, setReminderResult] = useState<any[] | null>(null);
const [reminderHistory, setReminderHistory] = useState<any[] | null>(null);
const [emailSubject, setEmailSubject] = useState("Fotos von {Kindernamen}");
const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>deine Fotos sind fertig und warten auf dich! Klicke einfach auf die Links unten, um direkt zu den Galerien zu gelangen:<br><br>{LinksHTML}<br><br>Viel Spaß beim Anschauen!");
const [emailSubject, setEmailSubject] = useState("Eure Bilder aus {Einrichtung} sind da! 📸");
const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>ich hoffe, es geht euch gut! 😊<br><br>Wir haben die wunderschönen Bilder vom Fotoshooting in {Einrichtung} fertiggestellt. Die Fotos von {Kindernamen} sind wirklich ganz toll geworden und warten nun darauf, von euch entdeckt zu werden!<br><br>Klicke einfach auf den untenstehenden Link, um direkt, sicher und bequem zu eurer persönlichen Galerie zu gelangen:<br><br>{LinksHTML}<br><br>Wenn ihr Fragen habt, meldet euch gerne jederzeit bei mir.<br><br>Viel Freude beim Anschauen und Aussuchen der Erinnerungen!");
const [isSendingEmails, setIsSendingEmails] = useState(false);
const [emailSendStatus, setEmailSendStatus] = useState<string | null>(null);
const [reminderTab, setReminderTab] = useState<'config' | 'preview' | 'history'>('config');
@@ -226,10 +226,16 @@ function App() {
if (!reminderResult) return [];
return reminderResult.map(row => {
let subject = emailSubject.replace(/{Kindernamen}/g, row["Kindernamen"]);
let einrichtung = selectedJob
? selectedJob.name.replace(/\(JOB\d+\)\s*/, '').replace(/Kindergarten\s+/gi, '').replace(/\s+\d{4}$/, '').trim()
: "eurer Einrichtung";
let subject = emailSubject
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung);
let body = emailBody
.replace(/{Name Käufer}/g, row["Name Käufer"])
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung)
.replace(/{LinksHTML}/g, row["LinksHTML"])
.replace(/\n/g, "<br>");
@@ -723,10 +729,16 @@ function App() {
setEmailSendStatus("Sende...");
const emailsToSend = reminderResult.map(row => {
let subject = emailSubject.replace(/{Kindernamen}/g, row["Kindernamen"]);
let einrichtung = selectedJob
? selectedJob.name.replace(/\(JOB\d+\)\s*/, '').replace(/Kindergarten\s+/gi, '').replace(/\s+\d{4}$/, '').trim()
: "eurer Einrichtung";
let subject = emailSubject
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung);
let body = emailBody
.replace(/{Name Käufer}/g, row["Name Käufer"])
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung)
.replace(/{LinksHTML}/g, row["LinksHTML"])
.replace(/\n/g, "<br>");

60
patch_frontend_email.py Normal file
View File

@@ -0,0 +1,60 @@
import sys
with open('fotograf-de-scraper/frontend/src/App.tsx', 'r') as f:
content = f.read()
# Replace the generic subject
old_subject = 'const [emailSubject, setEmailSubject] = useState("Fotos von {Kindernamen}");'
new_subject = 'const [emailSubject, setEmailSubject] = useState("Die Kindergarten-Fotos von {Kindernamen} sind da! 📸");'
# Replace the generic body
old_body = 'const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>deine Fotos sind fertig und warten auf dich! Klicke einfach auf die Links unten, um direkt zu den Galerien zu gelangen:<br><br>{LinksHTML}<br><br>Viel Spaß beim Anschauen!");'
new_body = 'const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>ich hoffe, es geht euch gut! 😊<br><br>Wir haben die wunderschönen Bilder vom Fotoshooting fertiggestellt. Die Fotos von {Kindernamen} sind wirklich ganz toll geworden und warten nun darauf, von euch entdeckt zu werden!<br><br>Klicke einfach auf den untenstehenden Link, um direkt, sicher und bequem zu eurer persönlichen Galerie zu gelangen:<br><br>{LinksHTML}<br><br>Wenn ihr Fragen habt, meldet euch gerne jederzeit bei mir.<br><br>Viel Freude beim Anschauen und Aussuchen der Erinnerungen!");'
if old_subject in content and old_body in content:
content = content.replace(old_subject, new_subject)
content = content.replace(old_body, new_body)
# We also need to add dynamic Einrichtungsname replacement to the parser
old_parser = """ let subject = emailSubject.replace(/{Kindernamen}/g, row["Kindernamen"]);
let body = emailBody
.replace(/{Name Käufer}/g, row["Name Käufer"])
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{LinksHTML}/g, row["LinksHTML"])
.replace(/\\n/g, "<br>");"""
new_parser = """ let einrichtung = selectedJob
? selectedJob.name.replace(/\\(JOB\\d+\\)\\s*/, '').replace(/Kindergarten\\s+/gi, '').replace(/\\s+\\d{4}$/, '').trim()
: "eurer Einrichtung";
let subject = emailSubject
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung);
let body = emailBody
.replace(/{Name Käufer}/g, row["Name Käufer"])
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{Einrichtung}/g, einrichtung)
.replace(/{LinksHTML}/g, row["LinksHTML"])
.replace(/\\n/g, "<br>");"""
content = content.replace(old_parser, new_parser)
# Note: We need to replace the parser in the send function too
old_sender = """ let subject = emailSubject.replace(/{Kindernamen}/g, row["Kindernamen"]);
let body = emailBody
.replace(/{Name Käufer}/g, row["Name Käufer"])
.replace(/{Kindernamen}/g, row["Kindernamen"])
.replace(/{LinksHTML}/g, row["LinksHTML"])
.replace(/\\n/g, "<br>");"""
content = content.replace(old_sender, new_parser)
# Add {Einrichtung} to the hint text in the UI
old_hint = 'Platzhalter: {Name Käufer}, {Kindernamen}, {LinksHTML}'
new_hint = 'Platzhalter: {Name Käufer}, {Kindernamen}, {Einrichtung}, {LinksHTML}'
content = content.replace(old_hint, new_hint)
with open('fotograf-de-scraper/frontend/src/App.tsx', 'w') as f:
f.write(content)
print("Frontend email template patched")
else:
print("Frontend code not found")

19
patch_frontend_email2.py Normal file
View File

@@ -0,0 +1,19 @@
import sys
with open('fotograf-de-scraper/frontend/src/App.tsx', 'r') as f:
content = f.read()
# Fix default text to include the new parameter
old_subject = 'const [emailSubject, setEmailSubject] = useState("Die Kindergarten-Fotos von {Kindernamen} sind da! 📸");'
new_subject = 'const [emailSubject, setEmailSubject] = useState("Eure Bilder aus {Einrichtung} sind da! 📸");'
old_body = 'const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>ich hoffe, es geht euch gut! 😊<br><br>Wir haben die wunderschönen Bilder vom Fotoshooting fertiggestellt. Die Fotos von {Kindernamen} sind wirklich ganz toll geworden und warten nun darauf, von euch entdeckt zu werden!<br><br>Klicke einfach auf den untenstehenden Link, um direkt, sicher und bequem zu eurer persönlichen Galerie zu gelangen:<br><br>{LinksHTML}<br><br>Wenn ihr Fragen habt, meldet euch gerne jederzeit bei mir.<br><br>Viel Freude beim Anschauen und Aussuchen der Erinnerungen!");'
new_body = 'const [emailBody, setEmailBody] = useState("Hallo {Name Käufer},<br><br>ich hoffe, es geht euch gut! 😊<br><br>Wir haben die wunderschönen Bilder vom Fotoshooting in {Einrichtung} fertiggestellt. Die Fotos von {Kindernamen} sind wirklich ganz toll geworden und warten nun darauf, von euch entdeckt zu werden!<br><br>Klicke einfach auf den untenstehenden Link, um direkt, sicher und bequem zu eurer persönlichen Galerie zu gelangen:<br><br>{LinksHTML}<br><br>Wenn ihr Fragen habt, meldet euch gerne jederzeit bei mir.<br><br>Viel Freude beim Anschauen und Aussuchen der Erinnerungen!");'
content = content.replace(old_subject, new_subject)
content = content.replace(old_body, new_body)
with open('fotograf-de-scraper/frontend/src/App.tsx', 'w') as f:
f.write(content)
print("Frontend email template patched 2")