Skip to content

Frontend Service

The React single-page app provides the user interface for AppStoreCat.

ComponentTechnology
FrameworkReact 19
Build toolVite 8
LanguageTypeScript
UI libraryshadcn/ui
CSSTailwind CSS v4
API clientGenerated with Orval
web/
├── src/
│ ├── pages/
│ │ ├── auth/ # Login, Register
│ │ ├── apps/ # App list, App detail
│ │ ├── changes/ # App changes, Competitor changes
│ │ ├── competitors/ # Competitor list
│ │ ├── discovery/ # App search, Publisher search, Trending
│ │ ├── explorer/ # Icons, Screenshots
│ │ ├── publishers/ # Publisher list, Publisher detail
│ │ └── Settings.tsx # User settings
│ ├── components/ # Shared UI components (CountrySelect, SyncingOverlay, ...)
│ └── lib/ # API client, helper utilities
├── orval.config.ts # API client generation configuration
└── Dockerfile # Development container
RoutePageDescription
/loginLoginUser authentication
/registerRegisterAccount creation
/appsApp ListTracked apps with a platform filter
/apps/:platform/:idApp DetailFull app view with tabs
/discovery/appsApp DiscoveryApp search (country_code)
/discovery/publishersPublisher DiscoveryPublisher search (country_code)
/discovery/trendingTrending ChartsBrowse trending charts (country_code)
/changes/appsApp ChangesStore listing changes for tracked apps
/changes/competitorsCompetitor ChangesChanges on competitor apps
/competitorsCompetitorsAll competitor apps
/explorer/screenshotsScreenshotsBrowse screenshots across apps
/explorer/iconsIconsBrowse app icons across apps
/publishersPublishersPublisher list
/publishers/:platform/:idPublisher DetailPublisher info + app catalog
/settingsSettingsUser profile and security

The app detail page has multiple tabs:

  • Listing — store listing with country + locale (locale) selectors. When the selected country is in unavailable_countries, StoreListingTab hides the content and shows a muted informational banner.
  • Versions — version history
  • Keywords — keyword density analysis
  • Competitors — competitor management
  • Changes — store listing change history
  • The CountrySelect component accepts a disabledCodes prop; countries in the app’s unavailable_countries list are marked unselectable, and the internal zz sentinel is hidden from the list.
  • All search/discovery screens send a country_code parameter.
  • Listing and change components use the selectedLocale state for the locale and the locale prop on the ChangeCard component.

SyncingOverlay displays a 4-step pipeline timeline: identity → listings → metrics → finalize statuses are marked as active / done / pending. UI-triggered refreshes go through POST /apps/{p}/{id}/sync, and status is polled via GET /apps/{p}/{id}/sync-status.

Types generated by Orval mirror the server schema; they include country_code, locale, unavailable_countries, SyncStatus, promotional_text, and icon_url.

Terminal window
make dev-web # Start the frontend
make logs-web # View frontend logs

The frontend is available at http://localhost:7461 and proxies API requests to the server.