Modernes, mobiles React-Frontend für persönliche Sprachnotizen mit n8n-CRUD-API als Backend.
- Notizen anzeigen in einer responsiven Kartenansicht (mobile first).
- Suche nach Titel, Kurzbeschreibung, Kategorie und Tags (Key Topics, People, Places).
- Filter nach Kategorie.
- Detailansicht mit vollständiger Zusammenfassung, Transkript, Topics, People, Places, Mood, Action Items, Reflection Notes und Bildstatus.
- CRUD vollständig:
- Erstellen (POST)
- Bearbeiten (PATCH, optional zentral auf PUT umstellbar)
- Löschen (DELETE mit Bestätigungsdialog)
- Robuste Datenverarbeitung für Felder, die als Array oder JSON-String von der API kommen können.
- Zustände für UX: Loading, Error, Empty State.
- Vite
- React
- TypeScript
- Tailwind CSS
- GitHub Actions (Build + Deploy)
- Tailscale + rsync für sicheren Deploy auf Proxmox-LXC
- Nginx als statisches Hosting
src/
├─ api/
│ └─ notesApi.ts
├─ components/
│ ├─ Header.tsx
│ ├─ NoteCard.tsx
│ ├─ NoteDetail.tsx
│ ├─ NoteForm.tsx
│ └─ StatusBadge.tsx
├─ types/
│ └─ voiceNote.ts
├─ utils/
│ └─ normalizeNote.ts
├─ App.tsx
├─ index.css
└─ main.tsx
- Abhängigkeiten installieren:
npm install.envanlegen (auf Basis von.env.example):
cp .env.example .env.envbefüllen:
VITE_API_BASE_URL=https://n8n.example.ts.net/webhook
VITE_API_KEY=change-me- Development-Server starten:
npm run dev- Produktionsbuild testen:
npm run build
npm run previewDie API-Aufrufe sind in src/api/notesApi.ts gekapselt.
GET ${VITE_API_BASE_URL}/notesPOST ${VITE_API_BASE_URL}/notesPATCH ${VITE_API_BASE_URL}/notes?id=<id>DELETE ${VITE_API_BASE_URL}/notes?id=<id>
Alle Requests senden automatisch:
x-api-key: <VITE_API_KEY>In src/api/notesApi.ts gibt es:
const UPDATE_METHOD: 'PATCH' | 'PUT' = 'PATCH';Falls dein n8n-Workflow PUT erwartet, ändere nur diese Konstante.
Die Felder keyTopics, people, places, mood, actionItems, reflectionNotes werden im UI kommasepariert eingegeben. Beim Speichern werden sie zu Arrays konvertiert.
Beim Laden akzeptiert das Frontend:
- echte Arrays (z. B.
['a', 'b']) - JSON-Strings (z. B.
"[\"a\",\"b\"]") - einfache CSV-Strings (z. B.
"a,b")
Workflow-Datei: .github/workflows/deploy.yml
- Push auf
master
- Checkout
- Node 20 Setup
npm cinpm run build- Join ins Tailnet via
tailscale/github-action@v3 - SSH-Key laden (
webfactory/ssh-agent) known_hostssetzendist/viarsyncauf deinen LXC übertragen
TAILSCALE_AUTHKEYDEPLOY_HOSTDEPLOY_USERDEPLOY_PATHDEPLOY_SSH_KEY
server {
listen 80;
server_name _;
root /var/www/voice-notes;
index index.html;
location / {
try_files $uri /index.html;
}
}VITE_API_KEY liegt im Browser-Bundle und ist daher für Benutzer sichtbar. Für echte Produktionsumgebungen sind empfehlenswert:
- ein Backend/BFF als Schutzschicht,
- kurzlebige Tokens,
- oder Zugriff nur über ein privates Netzwerk (z. B. Tailscale-only).