diff --git a/.gitignore b/.gitignore index 694c8bf36..dde0a7c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -128,6 +128,7 @@ dmypy.json .pyre/ .vscode/ +.idea/ out/ .next/ .DS_Store @@ -138,3 +139,6 @@ storybook-static/ # Sentry Auth Token .sentryclirc .astro + +# EuroPython website +src/content/days diff --git a/Makefile b/Makefile index 381952333..e434ba371 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,10 @@ BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) # Replace "/" and other non-alphanumeric characters with "-" SAFE_BRANCH := $(shell echo "$(BRANCH)" | sed 's/[^A-Za-z0-9-]/-/g') FORCE_DEPLOY ?= false +SITE_URL ?= "https://$(SAFE_BRANCH).ep-preview.click" .PHONY: build deploy dev clean install - safe_branch: @echo $(SAFE_BRANCH) @@ -47,6 +47,7 @@ build: preview: RELEASES_DIR = $(VPS_PREVIEW_PATH)/$(SAFE_BRANCH)/releases preview: TARGET = $(RELEASES_DIR)/$(TIMESTAMP) preview: + @echo "Preview site URL: $(SITE_URL)" # Output preview URL echo $(TARGET) @echo "\n\n**** Deploying preview of a branch '$(BRANCH)' (safe: $(SAFE_BRANCH)) to $(TARGET)...\n\n" $(REMOTE_CMD) "mkdir -p $(TARGET)" diff --git a/astro.config.mjs b/astro.config.mjs index bdd7f84d3..cf8ded4da 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -10,6 +10,7 @@ import rehypeAutolinkHeadings from "rehype-autolink-headings"; import metaTags from "astro-meta-tags"; import pagefind from "astro-pagefind"; import deleteUnusedImages from "astro-delete-unused-images"; +import preload from "astro-preload"; // https://astro.build/config export default defineConfig({ @@ -59,9 +60,9 @@ export default defineConfig({ "/sponsor/": "/sponsorship/sponsor/", "/voting/": "/programme/voting/", "/wasm-summit/": "/programme/wasm-summit/", - "/sessions/": "/programme/sessions/", }, integrations: [ + preload(), mdx(), sitemap(), react(), @@ -76,6 +77,10 @@ export default defineConfig({ build: { minify: true, }, + image: { + remotePatterns: [{ protocol: "https" }], + domains: ["programme.europython.eu", "placehold.co"], + }, experimental: { svg: true, }, diff --git a/package.json b/package.json index 443d0c0ac..83864ba4a 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,13 @@ "astro-delete-unused-images": "^1.0.3", "astro-meta-tags": "^0.3.1", "astro-pagefind": "^1.8.1", + "astro-preload": "^1.1.2", "clsx": "^2.1.1", "date-fns": "^4.1.0", "date-fns-tz": "^3.2.0", "hastscript": "^9.0.0", + "js-yaml": "^4.1.0", + "marked": "^15.0.7", "pagefind": "^1.3.0", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -40,6 +43,7 @@ "typescript": "^5.8.3" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", "prettier": "^3.4.2", "prettier-plugin-astro": "^0.14.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0594a015..1b9a1447a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ importers: astro-pagefind: specifier: ^1.8.1 version: 1.8.3(astro@5.5.2(jiti@1.21.7)(rollup@4.39.0)(typescript@5.8.3)(yaml@2.7.0)) + astro-preload: + specifier: ^1.1.2 + version: 1.1.2 clsx: specifier: ^2.1.1 version: 2.1.1 @@ -62,6 +65,12 @@ importers: hastscript: specifier: ^9.0.0 version: 9.0.1 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + marked: + specifier: ^15.0.7 + version: 15.0.7 pagefind: specifier: ^1.3.0 version: 1.3.0 @@ -90,6 +99,9 @@ importers: specifier: ^5.8.3 version: 5.8.3 devDependencies: + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 prettier: specifier: ^3.4.2 version: 3.5.3 @@ -1160,6 +1172,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -1299,6 +1314,9 @@ packages: peerDependencies: astro: ^2.0.4 || ^3 || ^4 || ^5 + astro-preload@1.1.2: + resolution: {integrity: sha512-96UHdATRp/K8iVysylYu0V5QMD3FXBqqj2+cUwHOmc0/+lstY5Xnb+A5UgmecbrfHpwMws5SQaOYZ1c63cQu/A==} + astro@5.5.2: resolution: {integrity: sha512-SOTJxB8mqxe/KEYEJiLIot0YULiCffyfTEclwmdeaASitDJ7eLM/KYrJ9sx3U5hq9GVI17Z4Y0P/1T2aQ0ZN3A==} engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -1877,6 +1895,11 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked@15.0.7: + resolution: {integrity: sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==} + engines: {node: '>= 18'} + hasBin: true + mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} @@ -3958,6 +3981,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/js-yaml@4.0.9': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -4110,6 +4135,8 @@ snapshots: pagefind: 1.3.0 sirv: 3.0.1 + astro-preload@1.1.2: {} + astro@5.5.2(jiti@1.21.7)(rollup@4.39.0)(typescript@5.8.3)(yaml@2.7.0): dependencies: '@astrojs/compiler': 2.11.0 @@ -4854,6 +4881,8 @@ snapshots: markdown-table@3.0.4: {} + marked@15.0.7: {} + mdast-util-definitions@6.0.0: dependencies: '@types/mdast': 4.0.4 diff --git a/src/content/sessions/.gitkeep b/public/assets/preloaded/.gitkeep similarity index 100% rename from src/content/sessions/.gitkeep rename to public/assets/preloaded/.gitkeep diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 000000000..8aed2cd00 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/placeholder.png b/public/placeholder.png new file mode 100644 index 000000000..25d8b8964 Binary files /dev/null and b/public/placeholder.png differ diff --git a/scripts/download-data.py b/scripts/download-data.py deleted file mode 100644 index 88a27bd2f..000000000 --- a/scripts/download-data.py +++ /dev/null @@ -1,79 +0,0 @@ -# /// script -# dependencies = [ -# "httpx", -# "PyYAML", -# ] -# requires-python = ">=3.11" -# /// - -from typing import Any -import httpx -import json -import pathlib -import shutil -import yaml - -ROOT = pathlib.Path(__file__).parents[1] - - -SESSIONS_URL = "https://programapi24.europython.eu/2024/sessions.json" -SPEAKERS_URL = "https://programapi24.europython.eu/2024/speakers.json" -SCHEDULE_DATA = "https://programapi24.europython.eu/2024/schedule.json" - - -def write_mdx(data: dict[str, Any], output_dir: pathlib.Path, content_key: str) -> None: - if output_dir.exists(): - shutil.rmtree(output_dir) - - output_dir.mkdir(parents=True, exist_ok=True) - - for key, value in data.items(): - filename = f"{key}.mdx" - path = output_dir / filename - - content = value.pop(content_key) or "" - - content = content.replace("<3", "❤️") - - frontmatter = yaml.dump(value, sort_keys=True) - - with path.open("w", encoding="utf-8") as f: - f.write(f"---\n{frontmatter}---\n\n{content}") - - -def download_data(url: str) -> dict[str, Any]: - with httpx.Client() as client: - response = client.get(url) - response.raise_for_status() - data = response.json() - - return data - - -def download() -> None: - speakers = download_data(SPEAKERS_URL) - sessions = download_data(SESSIONS_URL) - schedule = download_data(SCHEDULE_DATA) - - for session in sessions.values(): - session["speakers"] = [ - speakers[speaker_id]["slug"] for speaker_id in session.get("speakers", []) - ] - - for speaker in speakers.values(): - speaker["submissions"] = [ - sessions[session_id]["slug"] - for session_id in speaker.get("submissions", []) - if session_id in sessions - ] - - write_mdx(sessions, ROOT / "src/content/sessions", "abstract") - write_mdx(speakers, ROOT / "src/content/speakers", "biography") - - for day, data in schedule["days"].items(): - path = ROOT / f"src/content/days/{day}.json" - with path.open("w", encoding="utf-8") as f: - json.dump(data, f, indent=2) - - -download() diff --git a/src/assets/placeholder.png b/src/assets/placeholder.png new file mode 100644 index 000000000..25d8b8964 Binary files /dev/null and b/src/assets/placeholder.png differ diff --git a/src/assets/placeholder.svg b/src/assets/placeholder.svg new file mode 100644 index 000000000..80bd195ca --- /dev/null +++ b/src/assets/placeholder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/header/header-actions.astro b/src/components/header/header-actions.astro index 0138c1dfa..60bcfdb9c 100644 --- a/src/components/header/header-actions.astro +++ b/src/components/header/header-actions.astro @@ -1,5 +1,4 @@ --- -import ButtonLink from "../button-link/button-link.astro"; import Button from "@ui/Button.astro"; import HeaderButton from "./header-button.astro"; import Search from "astro-pagefind/components/Search"; diff --git a/src/components/keynoters/keynoter.astro b/src/components/keynoters/keynoter.astro index cc8c91af0..9767b0337 100644 --- a/src/components/keynoters/keynoter.astro +++ b/src/components/keynoters/keynoter.astro @@ -19,11 +19,9 @@ export interface Props { const { name, - slug, tagline, image, placeholder, - order, class: className, } = Astro.props; diff --git a/src/components/keynoters/keynoters.astro b/src/components/keynoters/keynoters.astro index a232aa8b5..4fefa0474 100644 --- a/src/components/keynoters/keynoters.astro +++ b/src/components/keynoters/keynoters.astro @@ -79,7 +79,7 @@ const placeholders = Math.max(0, 5 - keynoters.length); - +