|
| 1 | +# Landing page: Step, FooterColumn, SEO metadata, responsive |
| 2 | + |
| 3 | +Four landing-page issues. |
| 4 | + |
| 5 | +## What changed and why |
| 6 | + |
| 7 | +### #1345 - Step component + real "how it works" flow |
| 8 | +- `Step` takes an optional `href` and links the step title to the corresponding feature. |
| 9 | + The **step number is not passed in** - `landing.css` already derives it with a CSS |
| 10 | + `counter()` from the `<ol>` order, so it can't drift from the visual list. |
| 11 | +- The four steps now describe the real, shipped flow: connect a Stellar wallet -> browse |
| 12 | + markets -> place a bet -> claim a payout (i18n `howItWorks.*`), each linking to `/markets` |
| 13 | + or `/account/bets`. |
| 14 | +- Tests: title links to its feature; plain title without `href`; no hardcoded numbering in |
| 15 | + the DOM; the `LandingPage` data-driven test asserts the `<ol>` and the four step links. |
| 16 | + |
| 17 | +### #1346 - FooterColumn + real footer navigation |
| 18 | +- `FooterColumn` gains a `children` slot (for embeds) and an `external` link flag |
| 19 | + (`target="_blank"` + `rel="noopener noreferrer"`). |
| 20 | +- The footer columns were rewritten to routes that **exist**: Product (Markets `/markets`, |
| 21 | + Statistics `/statistics`, Create a market `/markets/create`), Resources (Documentation + |
| 22 | + GitHub, both external), and a "stay in the loop" column linking back to the hero signup |
| 23 | + form (a second `<NewsletterSignup>` would duplicate its field ids and break a11y). The |
| 24 | + dead `/docs`, `/github` (internal), `/discord`, `/privacy`, `/terms` links and the Legal |
| 25 | + column were removed - there are no such pages. |
| 26 | +- `e2e/landing-links-responsive.spec.ts` asserts every internal footer link resolves |
| 27 | + (`request.get(href)` < 400) - the CI link-check the AC asks for. |
| 28 | +- Tests: external vs internal link attributes; `children` render; the data-driven test now |
| 29 | + asserts real routes and the absence of the removed links. |
| 30 | + |
| 31 | +### #1347 - SEO metadata + structured data |
| 32 | +- `app/layout.tsx`: site-wide defaults - `metadataBase`, a `title` template, Open Graph |
| 33 | + `siteName`/`url`, Twitter `summary_large_image`. |
| 34 | +- `app/page.tsx` (kept server-side, still code-split via `next/dynamic` with `ssr: true` and |
| 35 | + the existing loading fallback): route-level `title` / `description` / canonical / full |
| 36 | + Open Graph + Twitter with an `/og-image.png`, plus an `Organization` + `WebSite` JSON-LD |
| 37 | + `<script type="application/ld+json">` (a build-time constant, server-rendered so |
| 38 | + link-unfurl crawlers see it). |
| 39 | +- Locale-specific metadata (#25) is out of scope here - the i18n layer only has an `en` |
| 40 | + bundle today; `SITE_URL` reads `NEXT_PUBLIC_SITE_URL` with a default. |
| 41 | +- Tests: `landing-metadata.test.ts` asserts the exported `metadata` shape and the layout |
| 42 | + defaults. |
| 43 | + |
| 44 | +### #1348 - responsive hardening |
| 45 | +- `overflow-wrap: anywhere` on hero/feature/step/footer text so a long word in a translated |
| 46 | + locale wraps instead of widening the page. |
| 47 | +- Grid tracks changed to `minmax(min(100%, 230px), 1fr)` so a track can shrink below its |
| 48 | + content's min-content size; `.footer-content { max-width: 100% }`. |
| 49 | +- A `@media (max-width: 360px)` block forces single-column grids and trims inline padding. |
| 50 | +- `e2e/landing-links-responsive.spec.ts` asserts `scrollWidth - clientWidth <= 1` at 320 / |
| 51 | + 768 / 1440. |
| 52 | + |
| 53 | +## How to test |
| 54 | + |
| 55 | +``` |
| 56 | +cd frontend |
| 57 | +PUPPETEER_SKIP_DOWNLOAD=true npm ci --legacy-peer-deps --ignore-scripts |
| 58 | +./node_modules/.bin/jest src/components/__tests__/Step.test.tsx \ |
| 59 | + src/components/__tests__/FooterColumn.test.tsx \ |
| 60 | + src/components/__tests__/LandingPage.dataDriven.test.tsx \ |
| 61 | + src/app/__tests__/landing-metadata.test.tsx |
| 62 | +``` |
| 63 | + |
| 64 | +- 37 tests pass across the touched suites; `page.test.tsx` (the dynamic-loading fallback |
| 65 | + test) still passes - the code-split + loading spinner were preserved. |
| 66 | +- `tsc --noEmit`: no errors in the touched files over the repo's pre-existing count. |
| 67 | +- `e2e/landing-links-responsive.spec.ts` not run here (needs the browser install). |
| 68 | +- Pre-existing on `main`, unchanged by this branch (verified against a clean `upstream/main` |
| 69 | + worktree - identical 30 failures): `Statistics.test.tsx`, `LandingPage.keyboard.test.tsx`, |
| 70 | + `LandingPage.accessibility.test.tsx`, `useAsync.test.ts`, `useReferral.test.ts`. |
| 71 | + |
| 72 | +## Breaking changes |
| 73 | + |
| 74 | +None. New props and metadata only. Footer link targets changed (removed dead links). |
| 75 | + |
| 76 | +## Related issues |
| 77 | + |
| 78 | +Closes #1345 |
| 79 | +Closes #1346 |
| 80 | +Closes #1347 |
| 81 | +Closes #1348 |
| 82 | + |
| 83 | +## PR Checklist |
| 84 | + |
| 85 | +- [x] Branch is up to date with `main` |
| 86 | +- [x] Commit messages follow Conventional Commits |
| 87 | +- [x] Tests added or updated for the change |
| 88 | +- [x] Documentation updated if behaviour changed (n/a) |
| 89 | +- [x] No secrets or credentials committed |
0 commit comments