[34588f42] Feature: BCC-Kopie an Kontaktadresse und UI-Übersicht für Formularantworten integriert

This commit is contained in:
2026-04-18 11:20:52 +00:00
parent aa3ff2998f
commit c458a9c26c
4 changed files with 64 additions and 1 deletions

View File

@@ -62,6 +62,8 @@ function App() {
const [isSendingRelease, setIsSendingRelease] = useState(false);
const [releaseMessage, setReleaseMessage] = useState("");
const [scheduledTime, setScheduledTime] = useState(""); // New state
const [releaseResponses, setReleaseResponses] = useState<any[] | null>(null);
const [isFetchingResponses, setIsFetchingResponses] = useState(false);
const fetchReleaseStats = async () => {
try {
@@ -75,6 +77,20 @@ function App() {
}
};
const fetchReleaseResponses = async () => {
setIsFetchingResponses(true);
try {
const response = await fetch(`${API_BASE_URL}/api/publish-request/responses`);
if (response.ok) {
const data = await response.json();
setReleaseResponses(data);
}
} catch (e) {
console.error("Failed to fetch release responses", e);
}
setIsFetchingResponses(false);
};
const handleUploadCodes = async () => {
setIsUploadingCodes(true);
setUploadMessage("Lädt hoch...");
@@ -248,6 +264,8 @@ function App() {
}
fetchLatestFile();
checkGmailAuth();
fetchReleaseStats();
fetchReleaseResponses();
}, [activeTab]);
const handleRefresh = () => fetchJobs(activeTab, true);
@@ -1053,6 +1071,45 @@ function App() {
{!isGmailAuthenticated && <p className="text-center text-[10px] mt-2 text-red-500">Gmail nicht verbunden.</p>}
{releaseMessage && <p className="text-center text-xs mt-2 font-bold text-indigo-600">{releaseMessage}</p>}
</div>
{/* Responses List */}
<div className="bg-white border border-gray-100 rounded-lg p-3 shadow-inner">
<div className="flex justify-between items-center mb-3">
<h6 className="text-[10px] font-bold text-gray-500 uppercase">Eingegangene Antworten</h6>
<button
onClick={fetchReleaseResponses}
disabled={isFetchingResponses}
className="text-[10px] bg-indigo-50 text-indigo-600 px-2 py-1 rounded hover:bg-indigo-100 transition-colors flex items-center gap-1"
>
{isFetchingResponses ? '...' : '🔄 Aktualisieren'}
</button>
</div>
{!releaseResponses || releaseResponses.length === 0 ? (
<p className="text-[10px] text-gray-400 italic text-center py-4">Noch keine Antworten eingegangen.</p>
) : (
<div className="max-h-40 overflow-y-auto rounded border border-gray-50">
<table className="min-w-full text-[10px] text-left">
<thead className="bg-gray-50 text-gray-400 sticky top-0">
<tr>
<th className="px-2 py-1">E-Mail</th>
<th className="px-2 py-1">Code</th>
<th className="px-2 py-1">Datum</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-50">
{releaseResponses.map((res, idx) => (
<tr key={idx} className="hover:bg-indigo-50/30">
<td className="px-2 py-1 text-gray-700 truncate max-w-[120px]" title={res.email}>{res.email}</td>
<td className="px-2 py-1 font-mono font-bold text-indigo-600">{res.code}</td>
<td className="px-2 py-1 text-gray-400">{new Date(res.used_at).toLocaleDateString('de-DE', {day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit'})}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
</div>