Skip to content

Commit 6ca8c48

Browse files
authored
feat: native comments, bug reports, dictionary, type safety (#200)
* feat: native comments, bug reports, word dictionary, and type safety overhaul Comments system: - Replace Giscus (GitHub Discussions) with native comment section on word pages - Comments table in Postgres (shared with bug reports via type field) - Real-time game result badges via single SQL query with correlated subquery - Badge rules: N/maxGuesses for wordle modes, N guesses for semantic, skip speed - Mode label only shown when user has 2+ badges for the same word - Basic moderation: profanity filter, URL blocking, rate limiting, hidden flag - Flat list, auth required to post, public to read Bug reports & feedback: - In-app report modal replacing GitHub Issues link in sidebar - Reports stored in comments table (type='report'/'feedback') - Auto-collects URL, browser, screen size, PWA status, language, mode - Optional email notification via Resend (works without it) Word page improvements: - WordDictionary: full Wiktionary entries (senses, etymology, IPA, forms) - WordTranslations: cross-language word links with SSR-safe language names - Fix hydration mismatch: translations now use server-resolved names instead of client-side cache (useNuxtData), eliminating 80+ hydration warnings that were corrupting Vue's component tree and breaking teleports/event handlers - Fix @unhead/vue dispose crash: merge 3 useHead/useSeoMeta calls into 1 - JSON-LD enriched with pronunciation and etymology from kaikki data - Image handling moved from HEAD-probe to server-provided image_url Type safety (45 errors → 0): - Add type annotations to all implicit-any parameters across server utils - Extend UiStrings and LanguageHelp types with missing optional properties - Fix null vs undefined mismatches in Vue components - Fix Nuxt route type recursion (ofetch import bypasses typed $fetch) - Add trackCustomEvent to analytics composable - Fix semantic.vue notification, game complete params, and compass types - Add TargetNeighbor model to Prisma schema (was orphaned, 4.4M rows) Passkey auth improvements (LoginModal rewrite): - Multi-step flow: main → passkey choice → register/authenticate - Platform-aware ordering (passkey first on iOS, Google first elsewhere) - Email sign-in placeholder Other: - Dictionary import script (scripts/import_dictionary.py) - Gitignore: design/, kaikki_processed/, public exploration files - TODO: leaderboard comments, comment admin tooling, Resend setup * style: format with Prettier + fix ruff lint errors
1 parent ed89cff commit 6ca8c48

59 files changed

Lines changed: 4026 additions & 1036 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ RESEND_API_KEY=""
3434
# Base URL for links in emails (verification, password reset).
3535
NUXT_BASE_URL="http://localhost:3000"
3636

37+
# ─── Reports ───
38+
# Email address for bug reports and feedback. Defaults to hugo@wordle.global.
39+
REPORT_EMAIL=""
40+
3741
# ─── Dev tools ───
3842
# Set to "true" to enable /api/auth/dev-login (bypasses OAuth for testing).
3943
# NEVER enable in production.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
docs/
66

77
# Design exploration HTML mockups (local only)
8+
design/
89
public/design-explorations/
10+
public/comments-exploration.html
911

1012
# Node.js / Frontend
1113
node_modules/
@@ -48,6 +50,9 @@ scripts/.freq_data
4850

4951
# Curation review temp files
5052
scripts/.curation_review/
53+
54+
# Processed kaikki dictionary data (190MB+, regenerate with import_dictionary.py)
55+
scripts/.kaikki_processed/
5156
.mcp.json
5257

5358
# Archive (legacy assets, not tracked)

TODO.md

Lines changed: 61 additions & 502 deletions
Large diffs are not rendered by default.

app.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { usePageDirection } from '~/composables/usePageDirection';
33
44
const { direction } = usePageDirection();
55
const { showLoginModal, closeLoginModal } = useLoginModal();
6+
const { showReportModal, closeReportModal } = useReportModal();
67
78
/** Direction-aware page transition. No 'out-in' — it causes blank screens
89
* because Nuxt's Suspense blocks the enter while out-in already removed
@@ -29,4 +30,5 @@ useHead({
2930
</NuxtLayout>
3031
<AccountBadgeEarned />
3132
<AccountLoginModal :visible="showLoginModal" @close="closeLoginModal" />
33+
<ReportModal :visible="showReportModal" @close="closeReportModal" />
3234
</template>

0 commit comments

Comments
 (0)