[34588f42] Feature: BCC-Kopie an Kontaktadresse und UI-Übersicht für Formularantworten integriert
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user