Frontend Service
The React single-page app provides the user interface for AppStoreCat.
Tech Stack
Section titled “Tech Stack”| Component | Technology |
|---|---|
| Framework | React 19 |
| Build tool | Vite 8 |
| Language | TypeScript |
| UI library | shadcn/ui |
| CSS | Tailwind CSS v4 |
| API client | Generated with Orval |
Directory Structure
Section titled “Directory Structure”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| Route | Page | Description |
|---|---|---|
/login | Login | User authentication |
/register | Register | Account creation |
/apps | App List | Tracked apps with a platform filter |
/apps/:platform/:id | App Detail | Full app view with tabs |
/discovery/apps | App Discovery | App search (country_code) |
/discovery/publishers | Publisher Discovery | Publisher search (country_code) |
/discovery/trending | Trending Charts | Browse trending charts (country_code) |
/changes/apps | App Changes | Store listing changes for tracked apps |
/changes/competitors | Competitor Changes | Changes on competitor apps |
/competitors | Competitors | All competitor apps |
/explorer/screenshots | Screenshots | Browse screenshots across apps |
/explorer/icons | Icons | Browse app icons across apps |
/publishers | Publishers | Publisher list |
/publishers/:platform/:id | Publisher Detail | Publisher info + app catalog |
/settings | Settings | User profile and security |
App Detail Tabs
Section titled “App Detail Tabs”The app detail page has multiple tabs:
- Listing — store listing with country + locale (
locale) selectors. When the selected country is inunavailable_countries,StoreListingTabhides the content and shows a muted informational banner. - Versions — version history
- Keywords — keyword density analysis
- Competitors — competitor management
- Changes — store listing change history
Country and Locale Semantics
Section titled “Country and Locale Semantics”- The
CountrySelectcomponent accepts adisabledCodesprop; countries in the app’sunavailable_countrieslist are marked unselectable, and the internalzzsentinel is hidden from the list. - All search/discovery screens send a
country_codeparameter. - Listing and change components use the
selectedLocalestate for the locale and thelocaleprop on theChangeCardcomponent.
Sync Experience
Section titled “Sync Experience”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.
Type Generation
Section titled “Type Generation”Types generated by Orval mirror the server schema; they include country_code, locale, unavailable_countries, SyncStatus, promotional_text, and icon_url.
Running
Section titled “Running”make dev-web # Start the frontendmake logs-web # View frontend logsThe frontend is available at http://localhost:7461 and proxies API requests to the server.