Shop Review B I-8: Webshop ohne Zahlung nur mit Zustimmung in Textform aktivieren

Das Textform-Formular (Haken, Datum, Weg, Chat-Vorlage) gilt wie beim Terminplaner auch
fuer den Webshop, wenn das Portal im Feld shop textformNoetig meldet. Kaestchentext und
Chat-Vorlage nennen die Unterlagen des Webshops, die Fassung und die Erklaerungen, die das
Portal im Nachweis speichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 09:45:31 +00:00
1 parent 0a2eab85d5
commit 00fa229235
4 files changed
+112 -23

No files matched your search

+11 -11
View File
@@ -114,10 +114,10 @@ function AnleitungPanel({ customerId, projectId, feature, reloadKey }) {
)
}
// Zustimmung des Kunden in Textform (Terminplaner im Modus on): Haken, Datum, Weg und die Textvorlage fuer den Chat. Die Pflichtangaben
// Zustimmung des Kunden in Textform (Terminplaner und Webshop im Modus on): Haken, Datum, Weg und die Textvorlage fuer den Chat. Die Pflichtangaben
// prueft textformBereit (funktionenView); das Portal prueft sie noch einmal. Links nur als geprueftes https (textformAnsicht).
function TextformPanel({ termine, value, onChange, projectId, today, disabled }) {
const ansicht = textformAnsicht(termine)
function TextformPanel({ funktion, feld, value, onChange, projectId, today, disabled }) {
const ansicht = textformAnsicht(feld, funktion)
const { label, links, vorlage } = ansicht
return (
<div className="area-row funktionen-panel">
@@ -140,7 +140,7 @@ function TextformPanel({ termine, value, onChange, projectId, today, disabled })
<span>Weg:</span>
{CHANNELS.map((c) => (
<label key={c} className="area-inline">
<input type="radio" name={`termine-weg-${projectId}`} value={c} checked={value.channel === c} disabled={disabled} onChange={() => onChange({ ...value, channel: c })} />
<input type="radio" name={`textform-weg-${funktion}-${projectId}`} value={c} checked={value.channel === c} disabled={disabled} onChange={() => onChange({ ...value, channel: c })} />
{channelLabel(c)}
</label>
))}
@@ -232,7 +232,7 @@ const LEERE_TEXTFORM = { confirmed: false, date: '', channel: '' }
export default function CustomerFunktionen({ customerId }) {
const [projects, setProjects] = useState(null)
const [termine, setTermine] = useState(null) // Portal-Feld termine: { textformNoetig, avvVersion, links }
const [felder, setFelder] = useState({ termine: null, shop: null }) // Portal-Felder termine und shop: { textformNoetig, avvVersion, links }
const [textform, setTextform] = useState(LEERE_TEXTFORM)
const [error, setError] = useState(null)
const [confirm, setConfirm] = useState(null) // { projectId, key, action }
@@ -247,7 +247,7 @@ export default function CustomerFunktionen({ customerId }) {
const load = useCallback(() => {
setError(null)
getFunktionen(customerId)
.then(({ projects: list, termine: feld }) => { setProjects(list || []); setTermine(feld || null) })
.then(({ projects: list, termine, shop: shopFeld }) => { setProjects(list || []); setFelder({ termine: termine || null, shop: shopFeld || null }) })
.catch((err) => setError(err.message || 'Funktionen konnten nicht geladen werden.'))
}, [customerId])
const loadShop = useCallback(() => {
@@ -257,14 +257,14 @@ export default function CustomerFunktionen({ customerId }) {
.catch((err) => setShopFehler(err.message || 'Webshop-Daten konnten nicht geladen werden.'))
}, [customerId])
useEffect(() => { load(); loadShop() }, [load, loadShop])
const nachEntscheidung = () => Promise.all([getFunktionen(customerId).then(({ projects: list, termine: feld }) => { setProjects(list || []); setTermine(feld || null) }), loadShop()])
const nachEntscheidung = () => Promise.all([getFunktionen(customerId).then(({ projects: list, termine, shop: shopFeld }) => { setProjects(list || []); setFelder({ termine: termine || null, shop: shopFeld || null }) }), loadShop()])
const save = async () => {
const { projectId, key, action } = confirm
setBusy(true)
setStatus(null)
try {
const mitTextform = textformNoetig(key, action, termine)
const mitTextform = textformNoetig(key, action, felder[key])
const antwort = await setFeature(customerId, key, {
projectId, action, note: note.trim(),
...(mitTextform ? { textformDate: textform.date, textformChannel: textform.channel } : {}),
@@ -306,8 +306,8 @@ export default function CustomerFunktionen({ customerId }) {
const isConfirming = confirm?.projectId === p.projectId && confirm?.key === f.key
const hatAnleitung = f.key === 'termine' && feature.state !== 'off'
const anleitungOffenHier = hatAnleitung && panelOffen(p.projectId)
const braucheTextform = isConfirming && textformNoetig(f.key, confirm.action, termine)
const textformFehlt = braucheTextform && !textformBereit({ ...textform, today: heute }, termine)
const braucheTextform = isConfirming && textformNoetig(f.key, confirm.action, felder[f.key])
const textformFehlt = braucheTextform && !textformBereit({ ...textform, today: heute }, felder[f.key])
return (
<Fragment key={`${p.projectId}:${f.key}`}>
<div className="area-row funktionen-row">
@@ -359,7 +359,7 @@ export default function CustomerFunktionen({ customerId }) {
</span>
</div>
{braucheTextform && (
<TextformPanel termine={termine} value={textform} onChange={setTextform} projectId={p.projectId} today={heute} disabled={busy} />
<TextformPanel funktion={f.key} feld={felder[f.key]} value={textform} onChange={setTextform} projectId={p.projectId} today={heute} disabled={busy} />
)}
{anleitungOffenHier && (
<AnleitungPanel customerId={customerId} projectId={p.projectId} feature={feature} reloadKey={panelReload[p.projectId] || 0} />