Six site improvements picked from a "what could be better" review, plus a Jest test suite covering the two areas with the trickiest money-handling history in this project (early-bird pricing tranches, donation-leg accounting): - "Add to calendar" .ics download on event pages and in confirmation emails - sitemap.xml, robots.txt, and Open Graph/Twitter metadata for public pages - Sentry error monitoring (backend + frontend), a no-op until SENTRY_DSN is set - Nightly local pg_dump backups with a Site Settings tab to browse/trigger/download - Admin audit trail for refunds, donations, manual registrations, event and settings changes, and staff-initiated cancellations - Jest tests reproducing and guarding against the 1.8.0 tranche-pricing bug and the 1.4.2 donation-balance-inflation bug Wallet passes (Google/Apple) were scoped out of this round — Apple Wallet needs a paid Apple Developer account the project doesn't have yet, and the user preferred shipping both together later rather than Google alone now. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { Share2, QrCode, CalendarPlus } from "lucide-react";
|
|
import QRCode from "qrcode";
|
|
import { API_BASE } from "@/lib/api";
|
|
|
|
export default function ClientActions({ event }: { event: any }) {
|
|
return (
|
|
<div className="flex gap-2">
|
|
<button
|
|
onClick={async () => {
|
|
try {
|
|
await navigator.share({
|
|
title: event.title,
|
|
text: event.description,
|
|
url: window.location.href,
|
|
});
|
|
} catch (err) {
|
|
console.error("Error sharing:", err);
|
|
}
|
|
}}
|
|
className="flex items-center gap-2 px-4 py-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors text-sm font-medium"
|
|
>
|
|
<Share2 className="w-4 h-4" />
|
|
Share
|
|
</button>
|
|
<button
|
|
onClick={async () => {
|
|
try {
|
|
const url = window.location.href;
|
|
const qrDataUrl = await QRCode.toDataURL(url);
|
|
const link = document.createElement("a");
|
|
link.href = qrDataUrl;
|
|
link.download = `${event.title}-qr.png`;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
} catch (err) {
|
|
console.error("Error generating QR code:", err);
|
|
}
|
|
}}
|
|
className="flex items-center gap-2 px-4 py-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors text-sm font-medium"
|
|
>
|
|
<QrCode className="w-4 h-4" />
|
|
Save QR
|
|
</button>
|
|
<a
|
|
href={`${API_BASE}/api/events/${event.id}/ics`}
|
|
download
|
|
className="flex items-center gap-2 px-4 py-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors text-sm font-medium"
|
|
>
|
|
<CalendarPlus className="w-4 h-4" />
|
|
Add to calendar
|
|
</a>
|
|
</div>
|
|
);
|
|
}
|