-
Notifications
You must be signed in to change notification settings - Fork 1
feat(ui): GitHub-issue feedback icon + tour step #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,16 +3,53 @@ | |
| import { onMount } from 'svelte'; | ||
| import { base } from '$app/paths'; | ||
| import { goto } from '$app/navigation'; | ||
| import { page } from '$app/stores'; | ||
| import { buildInfoFromEnv, loadManifest, type BuildInfo, type Manifest } from '$lib/shards'; | ||
| import BuildInfoFooter from '$lib/components/BuildInfo.svelte'; | ||
| import ThemeToggle from '$lib/components/ThemeToggle.svelte'; | ||
| import Tour from '$lib/components/Tour.svelte'; | ||
| import { tourStore, tourFlags } from '$lib/stores/tour'; | ||
|
|
||
| const FEEDBACK_REPO = 'sensein/ohbm2026'; | ||
|
|
||
| let manifest: Manifest | null = null; | ||
| const envBuildInfo: BuildInfo | null = buildInfoFromEnv(); | ||
| $: dataBuildInfo = manifest?.build_info ?? null; | ||
|
|
||
| /** | ||
| * Reactive GitHub-issue pre-fill URL. Recomputes on route change so | ||
| * the body reflects whichever page the user was on when they clicked. | ||
| */ | ||
| $: feedbackUrl = (() => { | ||
| const sha = | ||
| envBuildInfo?.code_revision_short ?? | ||
| dataBuildInfo?.code_revision_short ?? | ||
| '(unknown)'; | ||
| const here = $page.url.href; | ||
| const ua = typeof navigator !== 'undefined' ? navigator.userAgent : ''; | ||
| const body = [ | ||
| '<!-- Replace this template with your bug report or feature request. -->', | ||
| '', | ||
| '## What were you doing?', | ||
| '', | ||
| '## What happened?', | ||
| '', | ||
| '## What did you expect?', | ||
| '', | ||
| '---', | ||
| '', | ||
| `- page: ${here}`, | ||
| `- build: \`${sha}\``, | ||
| `- user-agent: ${ua}` | ||
| ].join('\n'); | ||
| const params = new URLSearchParams({ | ||
| labels: 'feedback', | ||
| title: '[feedback] ', | ||
| body | ||
| }); | ||
| return `https://github.com/${FEEDBACK_REPO}/issues/new?${params.toString()}`; | ||
| })(); | ||
|
Comment on lines
+23
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for constructing the GitHub issue URL is currently embedded directly within a reactive block in the layout. While functional, this logic is quite verbose and could be extracted into a dedicated helper function or a derived store in a separate utility file (e.g., |
||
|
|
||
| const SPA_REDIRECT_KEY = 'ohbm2026.spa.redirect'; | ||
|
|
||
| onMount(async () => { | ||
|
|
@@ -102,6 +139,40 @@ | |
| <a class="header-link" href={`${base}/about/`} data-testid="header-about-link"> | ||
| About | ||
| </a> | ||
| <!-- | ||
| Feedback icon — opens a pre-filled GitHub issue in a new tab. | ||
| The body templates the current page URL, the deploy SHA, and | ||
| the user-agent so a maintainer has the minimum context to | ||
| reproduce. Repo owner / project link from a const so it's | ||
| trivial to swap. | ||
| --> | ||
| <a | ||
| class="header-feedback" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| title="Report a bug or request a feature" | ||
| aria-label="Report a bug or request a feature on GitHub" | ||
| data-testid="header-feedback" | ||
| href={feedbackUrl} | ||
| > | ||
| <!-- Lucide-style "message-square-warning" icon — keeps the meaning | ||
| unambiguous: a comment bubble with an exclamation. --> | ||
| <svg | ||
| width="20" | ||
| height="20" | ||
| viewBox="0 0 24 24" | ||
| fill="none" | ||
| stroke="currentColor" | ||
| stroke-width="2" | ||
| stroke-linecap="round" | ||
| stroke-linejoin="round" | ||
| aria-hidden="true" | ||
| > | ||
| <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /> | ||
| <line x1="12" y1="8" x2="12" y2="12" /> | ||
| <line x1="12" y1="16" x2="12.01" y2="16" /> | ||
| </svg> | ||
| </a> | ||
| <ThemeToggle /> | ||
| </div> | ||
| </div> | ||
|
|
@@ -220,6 +291,20 @@ | |
| button.header-link:hover { | ||
| background: var(--accent-soft-bg); | ||
| } | ||
| .header-feedback { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| width: 2rem; | ||
| height: 2rem; | ||
| color: var(--text-muted); | ||
| border-radius: 4px; | ||
| text-decoration: none; | ||
| } | ||
| .header-feedback:hover { | ||
| color: var(--accent); | ||
| background: var(--accent-soft-bg); | ||
| } | ||
| .tour-cta { | ||
| display: flex; | ||
| align-items: center; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For SvelteKit applications, it is more idiomatic to use the
browserboolean from$app/environmentto guard client-side only globals likenavigator. This ensures consistent behavior across SSR and hydration.