Zum Inhalt springen

Anfrageformular in React Native erstellen – Angebotsanfrage per E-Mail

Ein Anfrageformular für React Native und Expo mit Auswahl von Leistung, Budget und Termin, das Ihnen jede Anfrage per E-Mail schickt und sie dem Kunden automatisch bestätigt.

Aktualisiert:

Das Video ist auf Englisch; die Schritte unten sind das vollständige Tutorial.

In diesem Tutorial bauen Sie einen Bildschirm für Angebotsanfragen in React Native: Der Kunde wählt eine Leistung und ein Budget, ergänzt Termin und Beschreibung, und Sie erhalten eine strukturierte E-Mail. Eine automatische Antwort bestätigt dem Kunden die Anfrage.

Sie brauchen: ein kostenloses Frontmail-Konto, ein Expo- oder React-Native-Projekt und etwa fünfzehn Minuten.

1. Postfach verbinden und Vorlagen anlegen

  1. E-Mail-Dienste → Dienst hinzufügen: Verbinden Sie Ihr Postfach oder Ihren Anbieter, Als Standard festlegen, Prüfen & speichern.
  2. Vorlagen → Aus der Galerie → Angebotsanfrage (Kategorie Geschäftlich) → Vorlage verwenden.
  3. Aus der Galerie → Automatische Antwort: Danke für Ihre Nachricht → Vorlage verwenden. Legen Sie Standardwerte für company_name und response_time fest und wählen Sie die Vorlage dann in der Anfragevorlage unter Einstellungen → Zustellung → Vorlage für automatische Antwort aus.

Parameter der Anfragevorlage: name, email, service, details (Pflicht) sowie phone, company, budget, deadline (optional, Termin als YYYY-MM-DD). service und budget akzeptieren nur die Werte auf dem Tab Parameter – verwenden Sie in der App dieselben Zeichenketten. Das Codebeispiel nutzt die Werte der englischen Vorlage; eine auf Deutsch angelegte Vorlage hat Website, Onlineshop, Mobile App, Beratung, Sonstiges und Unter 5.000 €, 5.000–20.000 €, 20.000–50.000 €, Über 50.000 €.

2. Mobile Apps erlauben und CAPTCHA aktivieren

  • Sicherheit → Mobile Apps → Mobile Apps erlauben → Speichern.
  • Anfragevorlage → Einstellungen → Schutz → CAPTCHA verlangen (Turnstile) – die App nutzt das gemeinsame Widget von Frontmail, keine Schlüssel nötig.

3. Installieren

npx expo install @frontmail/react-native @react-native-async-storage/async-storage react-native-webview

4. Formular bauen

Damit das Beispiel ohne zusätzliche Abhängigkeiten auskommt, sind die Auswahlmöglichkeiten einfache Chip-Buttons und der Termin wird als YYYY-MM-DD eingetippt. Setzen Sie gern Ihre bevorzugten Picker-Komponenten ein – es zählen nur die Werte, die Sie an send übergeben.

import { useRef, useState } from 'react';
import { Button, Pressable, Text, TextInput, View } from 'react-native';
import { FrontmailProvider, TurnstileWebView, useSendEmail, type TurnstileWebViewHandle } from '@frontmail/react-native';

const options = { publicKey: 'pk_…' };
const SERVICES = ['Website', 'E-shop', 'Mobile app', 'Consulting', 'Other'];
const BUDGETS = ['Under $5k', '$5k–20k', '$20k–50k', 'Over $50k'];

export default function App() {
  return (
    <FrontmailProvider options={options}>
      <QuoteForm />
    </FrontmailProvider>
  );
}

function Choice({ values, value, onChange }: { values: string[]; value?: string; onChange(v?: string): void }) {
  return (
    <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8 }}>
      {values.map((v) => (
        <Pressable key={v} onPress={() => onChange(v === value ? undefined : v)} accessibilityState={{ selected: v === value }}>
          <Text style={{ padding: 8, borderWidth: 1, borderRadius: 16, fontWeight: v === value ? '700' : '400' }}>{v}</Text>
        </Pressable>
      ))}
    </View>
  );
}

function QuoteForm() {
  const { send, status, error } = useSendEmail(null, 'tpl_…');
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [service, setService] = useState<string | undefined>(SERVICES[0]);
  const [budget, setBudget] = useState<string>();
  const [deadline, setDeadline] = useState('');
  const [details, setDetails] = useState('');
  const [token, setToken] = useState<string>();
  const turnstile = useRef<TurnstileWebViewHandle>(null);

  const onSend = async () => {
    await send({ name, email, service, budget, deadline, details }, { turnstileToken: token });
    setToken(undefined);
    turnstile.current?.reset(); // a token works only once
  };

  if (status === 'sent' || status === 'held') return <Text>Thanks! We’ve emailed you a confirmation.</Text>;

  return (
    <View style={{ gap: 12, padding: 16 }}>
      <TextInput placeholder="Name" value={name} onChangeText={setName} />
      <TextInput placeholder="Email" value={email} onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />
      <Text>What do you need?</Text>
      <Choice values={SERVICES} value={service} onChange={setService} />
      <Text>Budget (optional)</Text>
      <Choice values={BUDGETS} value={budget} onChange={setBudget} />
      <TextInput placeholder="Deadline (YYYY-MM-DD, optional)" value={deadline} onChangeText={setDeadline} />
      <TextInput placeholder="Project details" value={details} onChangeText={setDetails} multiline />
      <TurnstileWebView ref={turnstile} onToken={setToken} />
      <Button title="Request a quote" disabled={!token || !service || status === 'sending'} onPress={onSend} />
      {error && <Text>{error.message}</Text>}
    </View>
  );
}

Leere optionale Werte (kein Budget, leerer Termin) werden automatisch aus der E-Mail weggelassen.

5. Testen

Starten Sie die App und senden Sie eine Anfrage mit Ihrer eigenen E-Mail-Adresse. Sie erhalten die Anfrage und die Bestätigung; beide erscheinen im Verlauf. Validierungsfehler kommen als invalid_template_params zurück, das fehlerhafte Feld steht in error.details.

Eine Anfrage mit Bestätigung kostet zwei Credits. Sind die Credits aufgebraucht, werden Anfragen als held angenommen und nach dem Aufladen versendet – der Hook meldet status === 'held'.

Nächste Schritte

  • Führen Sie eine Liste aller Interessenten: Aktivieren Sie Kontakte sammeln in den Einstellungen der Vorlage.
  • Übergeben Sie { locale: 'de' } als zweites Argument von send, um eine Sprachvariante der Vorlage zu verwenden.
Alle Tutorials