fix(create): surface submit errors and fix keyboard overlap on mobile

The create-proposal submit had no error handling, so failures (e.g.
crypto.subtle unavailable outside a secure context) silently reset the
button with no feedback. Also set interactiveWidget so the mobile
keyboard resizes the layout instead of covering the sticky submit button.
This commit is contained in:
2026-07-30 10:16:56 +02:00
parent 6ea31e8ac0
commit 1b4ddd043a
2 changed files with 23 additions and 14 deletions
+22 -14
View File
@@ -55,22 +55,30 @@ export default function CreateClient() {
async function handleSubmit(data: ProposalFormData, _publish: boolean) {
setError('');
const key = await generateKey();
const payload = await encryptPayload(key, data);
const res = await fetch('/api/proposals/guest', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const json = await res.json();
if (!res.ok) {
setError('Something went wrong. Please check your inputs and try again.');
if (typeof crypto === 'undefined' || !crypto.subtle) {
setError('Your browser blocked secure encryption here (this page needs HTTPS). Try opening the site directly instead of through an in-app browser.');
return;
}
setLinks({
publicUrl: `${json.publicUrl}#k=${key}`,
manageUrl: `${json.manageUrl}#k=${key}`,
});
try {
const key = await generateKey();
const payload = await encryptPayload(key, data);
const res = await fetch('/api/proposals/guest', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const json = await res.json();
if (!res.ok) {
setError('Something went wrong. Please check your inputs and try again.');
return;
}
setLinks({
publicUrl: `${json.publicUrl}#k=${key}`,
manageUrl: `${json.manageUrl}#k=${key}`,
});
} catch {
setError('Something went wrong creating your proposal. Please try again.');
}
}
function copyLink(url: string) {
+1
View File
@@ -42,6 +42,7 @@ export const viewport: Viewport = {
themeColor: '#ec4899',
width: 'device-width',
initialScale: 1,
interactiveWidget: 'resizes-content',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {