Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
30ebca1
feat(website): add new Angular documentation website
tomalaforge Aug 15, 2026
189fa76
fix(website): address CodeRabbit review feedback on PR #1533
tomalaforge Aug 15, 2026
0334da9
feat(website): gate Google Analytics and AdSense behind a consent banner
tomalaforge Aug 15, 2026
d1ef34c
fix(website): make the consent banner stand out
tomalaforge Aug 15, 2026
e1b6af9
feat(website): add light/dark mode with a header toggle
tomalaforge Aug 15, 2026
5ff16d3
feat(website): add in-browser Monaco editor for challenge starter code
tomalaforge Aug 15, 2026
1efb219
feat(website): run challenges in a WebContainer and submit answers as…
tomalaforge Aug 15, 2026
c3538ea
revert(website): remove in-browser code editor and WebContainer runner
tomalaforge Aug 15, 2026
9776a2a
feat: one-click challenge onboarding — CLI, IDE deep links and Codesp…
tomalaforge Aug 15, 2026
6b98248
fix(cli): normalize bin path so npm publish keeps the executable
tomalaforge Aug 15, 2026
4384255
feat(website): manual-setup guides in try-challenge dialog; safer CLI…
tomalaforge Aug 15, 2026
92a325c
chore(cli): bump to 0.1.1 for the branch-switch commit guards
tomalaforge Aug 15, 2026
0a61b5c
style(website): larger, airier try-challenge dialog
tomalaforge Aug 15, 2026
2f64c57
docs(website): clarify the npx command runs in a terminal
tomalaforge Aug 15, 2026
ad1a139
fix(website): keep docs, landing and solutions readable on narrow scr…
tomalaforge Aug 15, 2026
bde4173
feat(cli): ask where to clone the fork
tomalaforge Aug 15, 2026
551583b
fix(website): address review comments on the docs rework
tomalaforge Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions website/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false

[*.md]
max_line_length = off
trim_trailing_whitespace = false
51 changes: 51 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.

# Compiled output
/dist
/tmp
/out-tsc
/bazel-out

# Node
/node_modules
npm-debug.log
yarn-error.log

# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/mcp.json
.history/*

# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
__screenshots__/

# System files
.DS_Store
Thumbs.db
.vercel
.env*

# generated content
src/app/generated/
.vercel
.env.local
5 changes: 5 additions & 0 deletions website/.postcssrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
12 changes: 12 additions & 0 deletions website/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"printWidth": 100,
"singleQuote": true,
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
}
4 changes: 4 additions & 0 deletions website/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
20 changes: 20 additions & 0 deletions website/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
42 changes: 42 additions & 0 deletions website/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "Changes detected"
},
"endsPattern": {
"regexp": "bundle generation (complete|failed)"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "Changes detected"
},
"endsPattern": {
"regexp": "bundle generation (complete|failed)"
}
}
}
}
]
}
59 changes: 59 additions & 0 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# AngularChallengesWebsite

This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.1.4.

## Development server

To start a local development server, run:

```bash
ng serve
```

Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.

## Code scaffolding

Angular CLI includes powerful code scaffolding tools. To generate a new component, run:

```bash
ng generate component component-name
```

For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:

```bash
ng generate --help
```

## Building

To build the project run:

```bash
ng build
```

This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.

## Running unit tests

To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:

```bash
ng test
```

## Running end-to-end tests

For end-to-end (e2e) testing, run:

```bash
ng e2e
```

Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.

## Additional Resources

For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
150 changes: 150 additions & 0 deletions website/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Angular Challenges Website — Rework Spec

Replacement of the Astro/Starlight docs (`docs/`) with a fully standalone **Angular v22 SSR** application living in `website/`. English only for v1. Deployed as a **new Vercel project**.

## Goals

1. Modern landing page.
2. Same documentation structure as today: left sidebar with **Guides**, **Leaderboard**, **Challenges**.
3. **Main goal:** browse community solutions directly on the website — list of solution PRs per challenge, and a GitHub-like **split diff viewer** when you open one.
4. (Phase 2 — later) Embedded editor to solve a challenge in the browser and submit it as a PR.

## Tech stack

| Concern | Choice |
|---|---|
| Framework | Angular v22, standalone components, signals, zoneless |
| SSR | `@angular/ssr` with Express server (server routes for API + OAuth) |
| Styling | Tailwind CSS v4 |
| Content | Markdown files (copied from `docs/src/content/docs`, English only), rendered server-side with `marked` + `shiki` for syntax highlighting |
| Diff rendering | PR patches from GitHub API, parsed and rendered with a custom split-diff component (Shiki-highlighted) |
| Package manager | pnpm (own workspace, standalone from the Nx monorepo — allows Angular v22 while the monorepo stays on 21.x) |
| Hosting | Vercel (SSR server as a Vercel serverless function, static assets on the CDN) |
| Analytics | Google Analytics (same tag `G-6BXJ62W6G5`), Google AdSense (same client id) |
| Comments | giscus (same repo/category config as today) |
| Newsletter | SendPulse embedded form (same form id) |

## Directory layout

```
website/
SPEC.md
package.json # standalone, not part of the Nx workspace
angular.json
vercel.json
src/
server.ts # Express + Angular SSR + API routes
main.ts / main.server.ts
content/
guides/*.md # copied from docs (en only)
challenges/<category>/*.md
leaderboard/*.md # intro texts
app/
layout/ # shell: header, sidebar, footer, mobile menu
pages/
landing/
guides/
leaderboard/
challenges/
challenge-detail/
solutions-list/
solution-diff/
shared/ # markdown renderer, diff viewer, github api client, ui bits
public/
```

## Routes (Angular Router, SSR)

| Route | Render mode | Description |
|---|---|---|
| `/` | prerender | Landing page |
| `/guides/:slug` | prerender | 7 guides (getting-started, resolve-challenge, checkout-answer, create-challenge, contribute, rebase, faq) |
| `/leaderboard/answers` `/leaderboard/challenges` `/leaderboard/commit` | SSR | Leaderboards from GitHub API |
| `/challenges/:category/:slug` | prerender (ISR-refreshable) | Challenge doc page |
| `/challenges/:category/:slug/solutions` | SSR | **NEW** — list of solution PRs |
| `/challenges/:category/:slug/solutions/:prNumber` | SSR | **NEW** — split diff view of one PR |
| `/auth/authorize`, `/auth/callback`, `/auth/logout` | server route | GitHub OAuth flow |
| `/api/*` | server route | JSON endpoints backing the pages (GitHub proxy + cache) |

Prerendered content pages get correct SEO meta (title, description, og tags) from the markdown frontmatter, matching what Starlight produces today.

## Layout & pages

### Landing page (rework)

Modern Tailwind design, dark-mode first (with light mode toggle), keeping today's content blocks:

- Sponsor banner (sponsor avatars via `/api/sponsors`, "Become a sponsor" CTA) — sponsors fetched with the server token, same as the current `api/sponsors.js`.
- Hero: logo, tagline "Start now and become an Angular Expert!", CTAs: *Get Started*, *Latest challenge*, *GitHub star*.
- Live GitHub stats strip (stars, forks, contributors, PRs merged) — cached server-side.
- Card grid: 65+ challenges, newsletter subscription, OSS maintainer, learn alongside others, contribute, interview prep.
- Footer: social links (GitHub, LinkedIn, X), attribution.

### Docs shell

- Left sidebar identical in structure to today: **Guides** (flat list), **Leaderboard** (3 entries, collapsible), **Challenges** (grouped by category: Angular, Forms, Nx, Performance, RxJS, …, ordered by `sidebar.order` / challenge number), with active-route highlighting, search-free v1 (see Open questions), mobile drawer.
- Right column: table of contents generated from markdown headings (desktop only).
- Header: logo + title, GitHub/LinkedIn/X icons, theme toggle, **Sign in with GitHub** button (avatar + logout when connected).

### Challenge detail page

- Markdown body (same content as today, including HTML `<details>` tips blocks).
- Info asides: how to get started, `npx nx serve <command>` with copy-to-clipboard.
- Footer metadata: author + contributors (avatars linking to GitHub), video/blog links when present in frontmatter.
- **NEW prominent "Browse solutions" button** → solutions list.
- giscus comment section (mapping: title, same as today).

### Solutions list (NEW — main goal)

`GET /api/challenges/:number/solutions` → GitHub search: PRs in `tomalaforge/angular-challenges` with labels `<challengeNumber>` + `answer` (and `answer author` surfaced separately as the author's solution), sorted by 👍 reactions.

UI: card list — author avatar/login, PR title, state (open/merged), 👍 count, comments count, created date, link to GitHub. Clicking a card opens the in-site diff view.

### Solution diff view (NEW — like the attached screenshot)

`GET /api/pulls/:number/files` → GitHub `pulls/:number/files` (per-file `patch`).

- **Split (side-by-side) view** like the screenshot: old/new line numbers, red removed / green added line backgrounds with char-level emphasis, collapsed unchanged regions with "N unmodified lines" expanders.
- Unified view toggle for mobile.
- File list header (tree or flat list) with per-file +/− counts; syntax highlighting via Shiki.
- Header: PR title, author, link to the PR on GitHub, 👍 reaction count. A reaction button ("this solution helped me 👍") when signed in.
- Handles GitHub API caveats: files without patches (binary/too large) show a "view on GitHub" fallback; >300 files pagination (never happens for challenges, but no crash).

### Leaderboards

Same three boards as today (challenges answered, challenges created, contributions), fed by cached server endpoints instead of client-side GitHub calls, so they render on the server and work for anonymous visitors without burning user rate limits.

## Authentication & GitHub API strategy

- **Reuse the existing GitHub OAuth app** (`GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` env vars) — one new callback URL must be added to it: `https://<new-domain>/auth/callback`.
- Token stored in an **httpOnly secure cookie** (improvement over today's localStorage), refresh handled server-side like today's `auth/refresh`.
- Signing in unlocks: reacting to solutions, higher rate limits for browsing, and (Phase 2) submitting challenges. Read-only browsing works anonymously.
- Server holds a **read-only PAT** (`GITHUB_TOKEN`) used for anonymous traffic, with an in-memory + `Cache-Control`/Vercel CDN cache (solutions list: 5 min; diffs: 1 h; leaderboards/stats/sponsors: 15 min) to stay far below rate limits.

## Vercel deployment

- New Vercel project (suggested name: `angular-challenges-website`) rooted at `website/`.
- Build: `pnpm build` (Angular SSR build) + `vercel.json` routing all non-static paths to the SSR function (Node 22 runtime).
- Env vars: `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `GITHUB_TOKEN`.
- Old docs project untouched; when the new site is validated, swap the domain over and retire `docs/`.

## Phase 2 (out of scope for now, spec'd later)

- "Try this challenge" button → embedded editor (StackBlitz WebContainers or Monaco — TBD).
- Submit flow: fork → branch → commit → PR from the user's account with correct title/labels (counts for the leaderboard).

## Milestones

1. **Scaffold**: Angular v22 SSR + Tailwind + Express server + Vercel deploy of a hello-world shell. ✅ deployable from day one.
2. **Content**: markdown pipeline, guides + challenge pages, sidebar, TOC, SEO meta.
3. **Solutions**: API endpoints + solutions list + split diff viewer.
4. **GitHub extras**: OAuth sign-in, leaderboards, stats, sponsors, reactions.
5. **Landing page** rework + giscus + newsletter + analytics.
6. Polish: 404, loading states, mobile, dark/light, redirects from old URLs.

## Open questions

1. **Search**: Starlight ships Pagefind search. v1 without search, or include a simple client-side search over titles? *(default: include a lightweight title/description search in the sidebar — cheap to do)*
2. **Old URL compatibility**: keep the exact Starlight paths (`/challenges/forms/48-avoid-losing-form-data/`) so existing links keep working when the domain swaps — assumed **yes**.
3. **Vercel access**: `vercel` CLI is not installed/authenticated on this machine, and login is interactive. Either run `vercel login` once in this workspace terminal, or create a token (vercel.com → Settings → Tokens) and provide it (`VERCEL_TOKEN`), and I'll create/link/deploy the project myself.
4. **Server PAT**: a fine-grained read-only `GITHUB_TOKEN` is needed for anonymous-traffic caching — to be created by Thomas and added to Vercel env (I'll list exact scopes: public repo read only).
Loading
Loading