diff --git a/.github/instructions/vue-ui-migration.instructions.md b/.github/instructions/vue-ui-migration.instructions.md index 7ca48aa..88a7a62 100644 --- a/.github/instructions/vue-ui-migration.instructions.md +++ b/.github/instructions/vue-ui-migration.instructions.md @@ -1,127 +1,307 @@ --- -description: "Use when rebuilding old-html-ver pages into Vue UI components, page layouts, composables, or styles for the bailuyuan website. Covers component extraction, custom UI design, and canonical legacy pattern selection." -name: "Vue UI Migration" -applyTo: "src/**/*.vue, src/**/*.js, src/**/*.css" +description: "Use when migrating old-html-ver pages into Vue for the bailuyuan website while preserving exact legacy layout, behavior, copy, deep-link behavior, and metadata. Covers removing the temporary review page and demo data, then rebuilding each legacy page 1:1 in Vue." +name: "Vue Legacy Page Parity Migration" +applyTo: "src/**/*.vue, src/**/*.js, src/**/*.css, vite.config.js, package.json, index.html" --- -# Bailuyuan Vue UI Migration Guidelines +# Bailuyuan Vue Legacy Page Parity Migration ## Goal -- Rebuild the legacy pages in `old-html-ver/` with Vue 3 components in `src/`. -- Do not use external UI component libraries. -- Recreate the site's visual language from the legacy HTML/CSS, but normalize duplicated styles into a smaller, cleaner component system. -- When similar legacy UIs use different implementations, keep the strongest pattern and discard weaker duplicates. +- Replace the temporary Vue component review shell with the real site. +- Migrate every page under `old-html-ver/` to Vue. +- Preserve the legacy site's layout, design, copy, interaction details, responsive behavior, and externally visible navigation behavior. +- Keep the data contracts in `public/data/` and `public/stats/` intact unless a task explicitly says otherwise. -## Source Priority +## Non-Negotiable Rules -- Treat `old-html-ver/js/components.js` as the source of truth for shared layout primitives: navbar, mobile menu, page hero, footer. -- Treat `old-html-ver/css/style.css` as the source of truth for global tokens and shared layout behavior. -- Treat `old-html-ver/announcements.html`, `old-html-ver/facilities.html`, and `old-html-ver/towns.html` plus their page CSS as the canonical source for search, filter, card, badge, and detail interaction patterns. -- Treat `old-html-ver/index.html` as the source for the home-page-only bento grid and hero interaction patterns. -- Treat `old-html-ver/stats.html`, `old-html-ver/sponsor.html`, and `old-html-ver/join.html` as sources for page-specific specialized components, not as the default style baseline for shared controls. +- Migrate with exact page parity. Do not redesign, modernize, normalize, simplify, or reinterpret the old site on your own. +- Do not keep the site as a temporary single-page component review shell. A real SPA is allowed, but it must preserve user-visible page behavior and must not remove deep-linking and direct access semantics from the legacy site. +- Do not keep `src/App.vue` as a component gallery or leave `src/demoData.js` in the real page flow. +- Do not replace production-like data with mock cards, placeholder lists, or hand-written demo objects once a page is being migrated. +- Do not silently change legacy copy, labels, icon meaning, filter order, badge meaning, modal sections, CTA wording, or page information architecture. +- Do not drop SEO metadata, structured data, verification tags, canonical URLs, or iframe targets from legacy pages unless explicitly requested. +- Do not introduce external UI kits such as Element Plus, Vuetify, Naive UI, or Ant Design Vue. -## Canonical Pattern Choices +## Current Vue Baseline -- Use the announcements/facilities/towns control bar as the standard filter UI: - - card-like `controls-section` - - `search-box` with leading icon - - labeled `filter-group` - - pill `filter-tag` buttons with a strong active state -- Prefer the facilities/towns card and modal structure as the base pattern for data-detail pages. -- Keep the announcement timeline as a dedicated page pattern instead of forcing it into the facilities/towns card layout. -- Keep leaderboard cards, donation cards, and join wizard cards as specialized components that inherit shared spacing, radius, shadow, and button rules from base UI primitives. -- If a sponsor or stats page control differs from the announcements/facilities/towns version, default to the latter unless the page has a real functional need for a custom variant. +- `src/App.vue` is currently a temporary review page for shared components. It is not a valid final page and must be removed or replaced as part of real migration work. +- `src/demoData.js` is temporary inspection data. It is useful only for base component review and must not remain as the source for migrated pages. +- `src/components/` already contains reusable layout, base, shared, and detail components. Reuse them only when they can reproduce the legacy page without changing the output. +- `vite.config.js` currently has only the default single-entry setup. Future migration work may keep a single-entry SPA or use multiple entries, but the final app must reproduce legacy navigation and direct-entry behavior instead of one showcase page. -## Components To Extract First +## Source Of Truth -- Layout primitives: - - `SiteNavbar` - - `MobileNavDrawer` - - `PageHero` - - `SiteFooter` -- Base UI primitives: - - `BaseButton` - - `BaseCard` - - `BaseModal` - - `BaseBadge` - - `SearchBox` - - `FilterTagGroup` - - `EmptyState` - - `LoadMoreButton` -- Shared content components: - - `FilterPanel` - - `FacilityCard` - - `TownCard` - - `AnnouncementTimeline` - - `AnnouncementCard` - - `LeaderboardCard` - - `PlayerCard` - - `DonationCard` - - `FeatureBentoGrid` - - `FeatureBentoCard` - - `JoinWizard` - - `DeviceCard` - - `PlaystyleCard` -- Detail components: - - `FacilityDetailModal` - - `TownDetailModal` - - `PlayerDetailModal` - - `SponsorModal` - - `ModalSection` +- Shared layout and global visual system: + - `old-html-ver/js/components.js` + - `old-html-ver/css/style.css` +- Page-specific HTML structure and page head metadata: + - `old-html-ver/*.html` +- Page-specific interactions: + - `old-html-ver/js/*.js` +- Page-specific styles: + - `old-html-ver/css/pages/*.css` +- Runtime data contracts: + - `public/data/*.json` + - `public/data/*.txt` + - `public/stats/summary.json` + - `public/stats/*.json` -## Expected Component Responsibilities +## Shared Legacy Primitives To Preserve -- Shared components must be prop-driven and reusable across multiple pages. -- Page components should compose shared components instead of duplicating old HTML blocks. -- Data-driven sections should accept structured props for badges, coordinates, contributor lists, rich text blocks, media blocks, and status labels. -- Repeated filter and search logic should move into Vue composables instead of being reimplemented in each page. +- Navbar, mobile menu, and footer come from `old-html-ver/js/components.js`. +- The reusable page hero pattern comes from `old-html-ver/js/components.js` plus `old-html-ver/css/style.css`. +- The translucent fixed top navigation, 44px header offset, rounded cards, soft shadows, and hero overlays come from `old-html-ver/css/style.css`. +- Shared sponsor parsing logic comes from `old-html-ver/js/data_utils.js` and the `data/sponsors.txt` format. + +## URL And Architecture Rules + +- A SPA architecture is allowed. +- Multiple page entries are also allowed. +- Choose the architecture that best preserves exact legacy behavior under static hosting. +- Direct access must still work for every migrated legacy page state that users can reasonably share or bookmark. +- For announcements, facilities, and towns, deep links must open the correct page and automatically expand or open the corresponding detail item or modal. +- It is acceptable to replace legacy `.html` paths with SPA routes only if external navigation remains stable enough for users and existing shared links continue to work or are intentionally redirected. +- If `vite.config.js` changes, keep deployment and static asset loading compatible with GitHub Pages style hosting. +- Keep relative fetch paths and static hosting compatibility. + +## Reuse Policy For Existing Vue Components + +- `SiteNavbar`, `MobileNavDrawer`, `PageHero`, and `SiteFooter` should be aligned to the legacy navbar, mobile menu, hero, and footer behavior from `old-html-ver/js/components.js`. +- `SearchBox`, `FilterTagGroup`, `FilterPanel`, `BaseModal`, `LoadMoreButton`, and related shared components are allowed starting points, but only if the migrated page still matches the legacy page exactly. +- `FeatureBentoGrid`, `JoinWizard`, `FacilityCard`, `TownCard`, `AnnouncementTimeline`, `LeaderboardCard`, `PlayerCard`, `DonationCard`, and detail modals are starting points, not final truth. Adjust them to the old page instead of adjusting the old page to the component. +- If a legacy page needs markup or behavior that existing components cannot express exactly, change the shared component or add a page-specific wrapper instead of forcing a mismatch. + +## Page Inventory And Migration Notes + +### Home Page + +- Source files: + - `old-html-ver/index.html` + - `old-html-ver/js/script.js` + - `old-html-ver/js/data_utils.js` + - `old-html-ver/css/style.css` +- Must preserve: + - skip link to main content + - full head metadata and structured data + - hero background, overlay, and title layout + - rotating subtitle words with the same cadence + - runtime timer from `2021-09-14T09:57:59` + - copy-to-clipboard server IP box and tooltip behavior + - live server status from `https://api.mcstatus.io/v2/status/java/mcpure.lunadeer.cn` + - online player tooltip list and offline fallback states + - bento feature grid with the same card count and hierarchy + - top sponsor section built from `data/sponsors.txt` + - crowdfunding section built from `data/fund_progress.txt` +- Migration notes: + - do not replace live status or counters with static placeholders + - keep the hidden crowdfunding section behavior that only shows when valid data exists + +### Announcements Page + +- Source files: + - `old-html-ver/announcements.html` + - `old-html-ver/js/announcements_script.js` + - `old-html-ver/css/pages/announcements.css` +- Data source: + - `public/data/announcements.json` +- Must preserve: + - page hero content and layout + - search input behavior + - category filter buttons and active states + - timeline layout and category-specific styling + - first card expanded by default + - click-to-expand with only one expanded card at a time + - direct link behavior that opens the matching item automatically + - share button that copies the deep link + - hidden edit mode triggered by typing `edit` + - rich content block rendering for text, image, and Bilibili video items +- Migration notes: + - keep the secret keyboard shortcut and console hint unless explicitly removed + - keep stable deep-link id generation semantics, whether implemented with hash or router state + +### Facilities Page + +- Source files: + - `old-html-ver/facilities.html` + - `old-html-ver/js/facilities_script.js` + - `old-html-ver/css/pages/facilities.css` +- Data source: + - `public/data/facilities.json` +- Must preserve: + - search input + - independent type and dimension filters + - facility card layout and status indicator styles + - detail modal content sections + - map link format to `https://mcmap.lunadeer.cn/` + - contributor avatar tags from Minotar + - Bilibili video block rendering in instructions and notes + - direct link behavior that auto-opens the correct facility modal +- Migration notes: + - do not flatten the modal content model into plain strings + - keep status meaning for `online`, `maintenance`, and `offline` + +### Towns Page + +- Source files: + - `old-html-ver/towns.html` + - `old-html-ver/js/towns_script.js` + - `old-html-ver/css/pages/towns.css` +- Data source: + - `public/data/towns.json` +- Must preserve: + - search input + - scale, type, and recruitment filters + - town card layout with logo image or gradient fallback + - icon badge meanings for scale, type, and recruitment + - detail modal structure + - founders and members sections with avatars + - coordinates secrecy behavior when `coordinatesSecret === true` + - direct link behavior that auto-opens the correct town modal +- Migration notes: + - keep gradient fallback behavior when no logo exists + - do not expose coordinates if the legacy data marks them as secret + +### Stats Page + +- Source files: + - `old-html-ver/stats.html` + - `old-html-ver/js/stats_script.js` + - `old-html-ver/css/pages/stats.css` +- Data sources: + - `public/stats/summary.json` + - `public/stats/*.json` + - generated by `scripts/statsprocess.py` +- Must preserve: + - updated-at text display + - six leaderboard blocks and their sort rules + - searchable player grid + - incremental load-more pagination with page size 24 + - player modal summary fields + - lazy loading of per-player detail JSON when a modal opens + - accordion structure for categorized detailed stats + - search inside large accordion sections +- Migration notes: + - do not swap in `src/demoData.js` player samples + - do not hand-edit generated stats JSON files + - keep raw sort semantics for `walk_raw` and `play_time_raw` + +### Sponsor Page + +- Source files: + - `old-html-ver/sponsor.html` + - `old-html-ver/js/sponsor_script.js` + - `old-html-ver/css/pages/sponsor.css` + - `old-html-ver/js/data_utils.js` +- Data sources: + - `public/data/sponsors.txt` + - `public/data/fund_progress.txt` when referenced by the page +- Must preserve: + - animated cumulative total amount display + - search input + - project filter generation from real sponsor data + - sponsor grid card layout and order + - sponsor modal with separate desktop QR and mobile button views + - mobile detection behavior + - empty state and load failure fallback text +- Migration notes: + - continue parsing `data/sponsors.txt` as `name, project, amount, [date]` + - keep newest-first display order by reversing the parsed list + +### Join Page + +- Source files: + - `old-html-ver/join.html` + - `old-html-ver/js/join_script.js` + - `old-html-ver/css/pages/join.css` + - `old-html-ver/js/marked.min.js` +- Data source: + - `public/data/convention.md` +- Must preserve: + - four-step wizard structure + - progress indicator states + - markdown loading for the convention step + - checkbox gating for agreement + - device selection cards + - Java and Bedrock edition toggle behavior + - launcher recommendation blocks per device and edition + - previous and next button states + - final step button set and tutorial rendering flow +- Migration notes: + - keep the lazy generation of step-3 tutorial content tied to the selected device and edition + - using a markdown parser is acceptable because the legacy page already relies on one + +### Doc, Map, And Photo Pages + +- Source files: + - `old-html-ver/doc.html` + - `old-html-ver/map.html` + - `old-html-ver/photo.html` +- Must preserve: + - navbar only plus fullscreen iframe layout + - inline page sizing behavior with the 44px navbar offset + - external iframe targets exactly as in the legacy site + - page-specific head metadata and structured data +- Migration notes: + - do not over-engineer these pages + - do not wrap them in extra containers that change the viewport sizing behavior + +## Demo Removal Rules + +- Remove the temporary showcase narrative from `src/App.vue` before treating migration as complete. +- Remove imports from `src/demoData.js` from any real page entry. +- Do not leave placeholder hero copy such as component review or UI audit text in production-facing pages. +- If demo data is still needed for isolated component development, keep it out of real page entry files and public routes. ## Styling Rules -- Keep the site's existing visual direction: soft cards, rounded corners, translucent navigation, strong hero imagery, restrained shadows, and Chinese content-first spacing. -- Reuse the legacy CSS variable vocabulary where it still makes sense, but consolidate it in the Vue codebase instead of copying page CSS wholesale. -- Do not copy-paste duplicated legacy class trees unless they are the chosen canonical pattern. -- Normalize spacing, radii, shadows, and interactive states across components. -- Preserve responsive behavior from the legacy site, especially navbar/mobile menu, hero scaling, filter wrapping, grid collapse, and modal usability. -- When creating styles, prefer local component styles or clearly organized shared styles over page-specific one-off overrides. +- Preserve the legacy CSS variable language and visual rhythm from `old-html-ver/css/style.css`. +- Match legacy spacing, card density, section order, control grouping, icon usage, and breakpoint behavior. +- Preserve hover states, animation cadence, focus states, and modal open-close feel where they are visible to users. +- Avoid large global style rewrites before parity is reached. -## Architecture Rules For Vue Work +## Interaction And Data Rules -- Build shared primitives before page-specific wrappers. -- Use slots only when content structure truly varies; otherwise use typed props with clear names. -- Keep interaction state inside the component or a focused composable such as search, filtering, modal visibility, and pagination. -- Avoid direct DOM manipulation when Vue state and template bindings can express the behavior. -- Preserve current data contracts from `public/data/` and `public/stats/` unless the task explicitly includes changing them. +- Prefer Vue state and template bindings over direct DOM mutation, but keep the visible behavior identical. +- Keep fetch paths relative for local files. +- Maintain current external integrations: + - `https://api.mcstatus.io/v2/status/java/mcpure.lunadeer.cn` + - `https://minotar.net/...` + - `https://crafatar.com/...` + - Bilibili embed iframes + - `https://schema.lunadeer.cn/...` + - `https://mcmap.lunadeer.cn/` + - `https://mcphoto.lunadeer.cn/` +- Render fallback text instead of crashing when remote requests fail, matching the legacy behavior. -## Legacy To Vue Mapping +## Recommended Migration Order -- `components.js` navbar/footer/hero -> shared layout components. -- Announcements page -> `FilterPanel` + `AnnouncementTimeline` + expandable `AnnouncementCard`. -- Facilities page -> `FilterPanel` + `FacilityCard` grid + `FacilityDetailModal`. -- Towns page -> `FilterPanel` + `TownCard` grid + `TownDetailModal`. -- Stats page -> `LeaderboardCard` grid + `PlayerCard` grid + `PlayerDetailModal` + pagination controls. -- Sponsor page -> `DonationCard` grid + `SponsorModal`, while still reusing shared search and filter primitives. -- Join page -> `JoinWizard`, `ProgressStep`, `DeviceCard`, `EditionToggle`, `PlaystyleCard`. -- Home page -> `PageHero` specialization + `FeatureBentoGrid` + sponsor highlight section. +1. Replace the review shell architecture so the project can serve legacy page URLs. +2. Wire shared layout pieces to match `old-html-ver/js/components.js` and `old-html-ver/css/style.css` precisely. +3. Migrate the simple iframe pages: `doc.html`, `map.html`, `photo.html`. +4. Migrate the filter-and-modal data pages: announcements, facilities, towns. +5. Migrate sponsor and stats using the real public data files. +6. Migrate the join wizard with markdown rendering. +7. Migrate the home page with live status, timers, sponsor totals, and crowdfunding. +8. Remove any remaining demo-only entry points and data. -## What To Avoid +## Verification Checklist -- Do not introduce Element Plus, Vuetify, Naive UI, Ant Design Vue, or similar UI kits. -- Do not keep one Vue component per old HTML page section if the section is really a shared pattern. -- Do not preserve inconsistent legacy styling just because it already exists. -- Do not port legacy imperative JavaScript event wiring directly into Vue components. -- Do not silently invent a new visual language that ignores the old site structure and tone. +- Compare new and old pages side by side on desktop and mobile. +- Check that page order, section order, and copy match. +- Check that filters, searches, empty states, and modal behavior match. +- Check deep links for announcements, facilities, and towns, including direct access that auto-opens the correct item or modal. +- Check the home page timer, subtitle rotation, copy-to-clipboard behavior, and live status fallbacks. +- Check stats leaderboard sorting, player search, pagination, and lazy-loaded details. +- Check sponsor total animation, project filters, and desktop vs mobile donation modal content. +- Check join wizard gating, device selection, edition toggle, and markdown rendering. +- Check iframe pages fill the viewport correctly below the fixed navbar. +- Check no production route depends on `src/demoData.js`. +- Check head metadata, structured data, and canonical URLs are preserved for each migrated page. -## Default Implementation Bias +## When Generating New Vue Code -- If multiple legacy versions exist, choose the version that is clearer, more reusable, and visually more stable. -- For search and filtering, bias toward the announcements/facilities/towns implementation. -- For detail dialogs, bias toward the facilities/towns modal structure. -- For cards on data listing pages, bias toward the facilities/towns content density instead of the lighter sponsor/stats cards unless the page truly needs the lighter form. - -## When Generating New Vue UI - -- State which legacy page and which legacy pattern you are mapping from. -- List which shared component should be reused before creating a new one. -- If creating a new component, explain why an existing shared primitive is insufficient. -- Keep markup semantic and accessible: buttons for actions, labels for fields, dialog semantics for modals, keyboard-friendly navigation states. \ No newline at end of file +- State the exact legacy page being migrated. +- List the specific legacy files used as the source of truth. +- Explain which existing Vue components are being reused and why they still allow exact parity. +- If adding a new component or composable, explain what legacy behavior requires it. +- Treat parity regressions as bugs, even if the Vue implementation looks cleaner internally. \ No newline at end of file diff --git a/index.html b/index.html index ee9ecdf..bddca53 100644 --- a/index.html +++ b/index.html @@ -3,11 +3,102 @@
- -