mirror of
https://github.com/Coldsmiles/infstarweb.git
synced 2026-04-23 02:30:41 +08:00
feat: add TownsPage and router configuration
- Created TownsPage.vue to display a list of towns with filtering options and a modal for details. - Implemented a router.js file to manage application routes, including the new towns page.
This commit is contained in:
@@ -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.
|
||||
- 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.
|
||||
Reference in New Issue
Block a user