From 456832aad39eadcf8116c32a078e31074806cbdc Mon Sep 17 00:00:00 2001 From: jschoeny Date: Thu, 15 Jan 2026 19:21:01 -1000 Subject: [PATCH] Add optional verification contact field --- src/app/hack/[slug]/actions.ts | 8 +++- src/app/hack/[slug]/page.tsx | 19 ++++++++- src/app/submit/actions.ts | 2 + src/components/Hack/HackSubmitForm.tsx | 41 ++++++++++++++++++- src/types/db.ts | 3 ++ ..._hack_verification_contact_info_column.sql | 2 + 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 supabase/migrations/20260116042815_hack_verification_contact_info_column.sql diff --git a/src/app/hack/[slug]/actions.ts b/src/app/hack/[slug]/actions.ts index fc76a37..86bebf6 100644 --- a/src/app/hack/[slug]/actions.ts +++ b/src/app/hack/[slug]/actions.ts @@ -30,6 +30,7 @@ export interface HackMetadata { language: string | null; is_archive: boolean; completion_status: Database["public"]["Enums"]["Completion Status"] | null; + verification_contact_info: string | null; }; images: string[]; tags: string[]; @@ -59,12 +60,17 @@ export async function getHackMetadata(slug: string): Promise ) )} + {isAdmin && hack.verification_contact_info && ( +
+
+
+ +
+
+

+ Verification Contact Information +

+
+ {hack.verification_contact_info} +
+
+
+
+ )} )} diff --git a/src/app/submit/actions.ts b/src/app/submit/actions.ts index 94fc674..9cb10a1 100644 --- a/src/app/submit/actions.ts +++ b/src/app/submit/actions.ts @@ -50,6 +50,7 @@ export async function prepareSubmission(formData: FormData) { const tags = (formData.get("tags") as string)?.split(",").map((t) => t.trim()).filter(Boolean) || []; const original_author = (formData.get("original_author") as string)?.trim() || null; const permission_from = (formData.get("permission_from") as string)?.trim() || null; + const verification_contact_info = (formData.get("verification_contact_info") as string)?.trim() || null; const is_archive = formData.get("is_archive") === "true"; // For archives, version is not required; for regular hacks, it is @@ -93,6 +94,7 @@ export async function prepareSubmission(formData: FormData) { patch_url: "", original_author: original_author || null, permission_from: permission_from || null, + verification_contact_info: verification_contact_info || null, current_patch: null, // Archives don't have patches } as HackInsert; diff --git a/src/components/Hack/HackSubmitForm.tsx b/src/components/Hack/HackSubmitForm.tsx index 3abf025..7cbbacc 100644 --- a/src/components/Hack/HackSubmitForm.tsx +++ b/src/components/Hack/HackSubmitForm.tsx @@ -108,6 +108,7 @@ export default function HackSubmitForm({ const [twitter, setTwitter] = React.useState(() => initialDraftRef.current?.twitter || ""); const [pokecommunity, setPokecommunity] = React.useState(() => initialDraftRef.current?.pokecommunity || ""); const [github, setGithub] = React.useState(() => initialDraftRef.current?.github || ""); + const [verificationContactInfo, setVerificationContactInfo] = React.useState(() => initialDraftRef.current?.verificationContactInfo || ""); const [tags, setTags] = React.useState(() => (Array.isArray(initialDraftRef.current?.tags) ? initialDraftRef.current.tags : [])); const [showMdPreview, setShowMdPreview] = React.useState(() => !!initialDraftRef.current?.showMdPreview); const [originalAuthor, setOriginalAuthor] = React.useState(() => { @@ -287,7 +288,7 @@ export default function HackSubmitForm({ const data = JSON.parse(raw); if (data && typeof data === "object") { const isEmpty = - !title && !summary && !description && !baseRom && !platform && !version && !language && !completionStatus && !boxArt && !discord && !twitter && !pokecommunity && !github && (!tags || tags.length === 0) && !originalAuthor; + !title && !summary && !description && !baseRom && !platform && !version && !language && !completionStatus && !boxArt && !discord && !twitter && !pokecommunity && !github && !verificationContactInfo && (!tags || tags.length === 0) && !originalAuthor; if (isEmpty) { let applied = false; if (typeof data.title === "string") setTitle(data.title); @@ -316,6 +317,8 @@ export default function HackSubmitForm({ if (typeof data.pokecommunity === "string") applied = applied || !!data.pokecommunity; if (typeof data.github === "string") setGithub(data.github); if (typeof data.github === "string") applied = applied || !!data.github; + if (typeof data.verificationContactInfo === "string") setVerificationContactInfo(data.verificationContactInfo); + if (typeof data.verificationContactInfo === "string") applied = applied || !!data.verificationContactInfo; if (Array.isArray(data.tags)) setTags(data.tags.filter((t: any) => typeof t === "string")); if (Array.isArray(data.tags)) applied = applied || data.tags.length > 0; // Only load originalAuthor from draft if customCreator is not provided @@ -346,7 +349,7 @@ export default function HackSubmitForm({ if (!d || typeof d !== "object") return; // Don't count originalAuthor if customCreator is provided const hasAny = Boolean( - d.title || d.summary || d.description || d.baseRom || d.platform || d.version || d.language || d.completionStatus || d.boxArt || d.discord || d.twitter || d.pokecommunity || d.github || (Array.isArray(d.tags) && d.tags.length > 0) || (!customCreator && d.originalAuthor) + d.title || d.summary || d.description || d.baseRom || d.platform || d.version || d.language || d.completionStatus || d.boxArt || d.discord || d.twitter || d.pokecommunity || d.github || d.verificationContactInfo || (Array.isArray(d.tags) && d.tags.length > 0) || (!customCreator && d.originalAuthor) ); if (hasAny) { hydratedFromDraftRef.current = true; setRestoredDraft(true); } }, [dummy, draftKey, customCreator]); @@ -369,6 +372,7 @@ export default function HackSubmitForm({ twitter, pokecommunity, github, + verificationContactInfo, tags, step, showMdPreview, @@ -402,6 +406,7 @@ export default function HackSubmitForm({ twitter, pokecommunity, github, + verificationContactInfo, tags, originalAuthor, customCreator, @@ -441,6 +446,7 @@ export default function HackSubmitForm({ if (twitter) fd.set('twitter', twitter); if (pokecommunity) fd.set('pokecommunity', pokecommunity); if (github) fd.set('github', github); + if (verificationContactInfo) fd.set('verification_contact_info', verificationContactInfo); if (tags.length) fd.set('tags', tags.join(',')); if (isArchive) { fd.set('is_archive', 'true'); @@ -724,6 +730,7 @@ export default function HackSubmitForm({ setTwitter(""); setPokecommunity(""); setGithub(""); + setVerificationContactInfo(""); setTags([]); setNewCoverFiles([]); setCoverErrors([]); @@ -1146,6 +1153,36 @@ export default function HackSubmitForm({ )} + + {!profile?.verified && ( +
+ +

+ Help us verify your account by providing contact information from a platform where your message/post history can be verified (e.g., Discord, PokéCommunity). This information will only be visible to admins during the approval process. +

+ {!isDummy ? ( +