Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# API backend URL (BridgeStack FastAPI server)
# The Vite dev server proxies /api requests to this URL
VITE_API_URL=http://localhost:8000
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,17 @@ jobs:
with:
args: --accept 200,204,301,302,403,429 --exclude-mail --exclude "localhost|127.0.0.1|example.com|twitter.com|x.com|linkedin.com|facebook.com|instagram.com" --timeout 30 --max-retries 2 "**/*.html" "**/*.md"
fail: false

build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci --legacy-peer-deps
- run: npm run lint
- run: npm run format:check
- run: npm run test
- run: npm run build
30 changes: 30 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy Docs

on:
push:
branches: [main]
paths: ['docs/**']

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
with:
path: docs
- id: deployment
uses: actions/deploy-pages@v4
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist/
node_modules/
package-lock.json
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2
}
Empty file added docs/.nojekyll
Empty file.
38 changes: 38 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# ViewStack

**ViewStack** is the frontend layer of the [OpenStacks](https://openstacks.dev) platform — a React dashboard for exploring Indian development data including government schemes, state indicators, budgets, and geographic coverage.

## Key Features

- **Dashboard** — Summary cards with scheme, state, indicator, and sector counts
- **States Explorer** — Browse states/UTs with region filtering, population data, and district breakdowns
- **Scheme Browser** — Filter government schemes by sector and level, view budget trends and coverage
- **Indicator Explorer** — Interactive charts comparing development indicators across states

## Tech Stack

| Layer | Technology |
|-------|-----------|
| UI Framework | React 19 |
| Routing | React Router 7 |
| Charts | Recharts 3 |
| Build Tool | Vite 5 |
| Testing | Vitest + React Testing Library |
| Linting | ESLint 10 + Prettier |
| API Backend | [BridgeStack](https://github.com/Varnasr/BridgeStack) (FastAPI) |

## Getting Started

```bash
# Clone the repo
git clone https://github.com/Varnasr/ViewStack.git
cd ViewStack

# Install dependencies
npm install

# Start dev server (requires BridgeStack running on port 8000)
npm run dev
```

Visit `http://localhost:5173` to see the dashboard.
10 changes: 10 additions & 0 deletions docs/_coverpage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ViewStack

> A React dashboard for exploring Indian development data

- Built with React 19, Recharts 3, React Router 7
- Part of the [OpenStacks](https://openstacks.dev) ecosystem
- Open source under MIT license

[Get Started](#getting-started)
[GitHub](https://github.com/Varnasr/ViewStack)
23 changes: 23 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- **Getting Started**
- [Introduction](/)
- [Quick Start](quickstart.md)
- [Project Structure](structure.md)

- **Architecture**
- [Overview](architecture.md)
- [API Client](api-client.md)
- [Components](components.md)

- **Development**
- [Development Guide](development.md)
- [Testing](testing.md)
- [Code Style](code-style.md)

- **Best Practices**
- [Accessibility](accessibility.md)
- [Performance](performance.md)
- [Security](security.md)

- **Contributing**
- [How to Contribute](contributing.md)
- [Commit Conventions](commits.md)
33 changes: 33 additions & 0 deletions docs/accessibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Accessibility

ViewStack follows web accessibility best practices to ensure the dashboard is usable by everyone.

## Current Implementation

### Skip Navigation
A "Skip to main content" link appears on keyboard focus, allowing users to bypass the navigation.

### ARIA Roles
- `LoadingState` uses `role="status"` with `aria-live="polite"` for screen reader announcements
- `ErrorState` uses `role="alert"` for immediate error announcements
- `FilterBar` uses `role="search"` with `aria-label` on each select
- Navigation uses `aria-label="Main navigation"`
- Footer uses `role="contentinfo"`

### Semantic HTML
- Tables use `<caption>` (visually hidden) for screen readers
- Table headers use `scope="col"` for proper association
- Interactive table rows have `role="button"`, `tabIndex`, and keyboard handlers

### Keyboard Navigation
- `DataTable` rows with `onRowClick` support Enter and Space key activation
- All interactive elements are focusable and keyboard-operable

## Best Practices for Contributors

1. **Always add `aria-label`** to interactive elements without visible text
2. **Use semantic HTML** — prefer `<button>` over `<div onClick>`
3. **Provide text alternatives** for color-coded information (badges include text labels)
4. **Test with keyboard only** — tab through the page, ensure all actions are reachable
5. **Use the `sr-only` CSS class** for screen-reader-only content
6. **Never remove focus outlines** without providing an alternative indicator
56 changes: 56 additions & 0 deletions docs/api-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# API Client

The API client (`src/api/client.js`) centralizes all communication with the BridgeStack backend.

## Base URL

All requests go to `/api/v1/*`, proxied to `http://localhost:8000` in development.

## Available Methods

### Geography

```js
api.getStates(region?) // GET /api/v1/geography/states
api.getState(id) // GET /api/v1/geography/states/:id
api.getDistricts(stateId?) // GET /api/v1/geography/districts
```

### Sectors

```js
api.getSectors() // GET /api/v1/sectors/
```

### Indicators

```js
api.getIndicators(sectorId?) // GET /api/v1/indicators/
api.getIndicator(id) // GET /api/v1/indicators/:id
api.getIndicatorValues(indicatorId, stateId)
// GET /api/v1/indicators/values/
```

### Policies

```js
api.getSchemes(sectorId?, level?) // GET /api/v1/policies/schemes
api.getScheme(id) // GET /api/v1/policies/schemes/:id
api.getBudgets(schemeId?) // GET /api/v1/policies/budgets
```

### Tools

```js
api.getTools(stack?) // GET /api/v1/tools/
```

## Error Handling

The client throws on non-OK responses with the HTTP status code. Catch errors in the calling component:

```jsx
api.getStates()
.then(setStates)
.catch((e) => setError(e.message))
```
47 changes: 47 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Architecture Overview

## System Design

ViewStack is the **frontend layer** in the OpenStacks ecosystem:

```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ ViewStack │────▶│ BridgeStack │────▶│ DataStack │
│ (React) │ API │ (FastAPI) │ DB │ (PostgreSQL)│
└─────────────┘ └──────────────┘ └─────────────┘
```

- **ViewStack** — React SPA, renders dashboards and visualizations
- **BridgeStack** — REST API, handles data queries and aggregation
- **DataStack** — Data pipeline, ETL from government sources

## Frontend Architecture

### Routing

React Router handles client-side routing with these routes:

| Path | Page | Description |
|------|------|-------------|
| `/` | Dashboard | Summary overview |
| `/states` | States | State/UT listing |
| `/states/:stateId` | StateDetail | State info + districts |
| `/schemes` | Schemes | Scheme listing |
| `/schemes/:schemeId` | SchemeDetail | Budget + coverage |
| `/indicators` | Indicators | Interactive explorer |

### Data Flow

1. Page mounts → calls `api.*` method
2. `api/client.js` constructs URL and calls `fetch`
3. Response is set in component state via `useState`
4. Component renders data (tables, cards, charts)
5. Error/loading states handled via `ErrorState`/`LoadingState`

### API Client

All API calls are centralized in `src/api/client.js`. This provides:

- Single point of change for base URL, headers, auth
- Consistent error handling (`throw` on non-OK responses)
- Clean separation between data fetching and rendering
52 changes: 52 additions & 0 deletions docs/code-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Code Style

## Tools

| Tool | Purpose | Config File |
|------|---------|-------------|
| ESLint | Linting | `eslint.config.js` |
| Prettier | Formatting | `.prettierrc` |
| EditorConfig | Editor settings | `.editorconfig` |

## Prettier Rules

- No semicolons
- Single quotes
- Trailing commas (all)
- 100 character line width
- 2 space indentation

## ESLint Rules

- React Hooks rules enforced (rules-of-hooks, exhaustive-deps)
- Accessibility rules via `eslint-plugin-jsx-a11y`
- Unused variables warned (except `_`-prefixed args)

## Commit Conventions

Commits must use a prefix:

| Prefix | Usage |
|--------|-------|
| `Add:` | New feature |
| `Fix:` | Bug fix |
| `Update:` | Enhancement to existing feature |
| `Refactor:` | Code restructuring |
| `Docs:` | Documentation changes |
| `Test:` | Test additions/changes |
| `CI:` | CI/CD changes |
| `Chore:` | Maintenance tasks |

Example: `Add: budget trend chart to scheme detail page`

The commit-msg hook validates this automatically.

## Pre-commit Checks

The pre-commit hook blocks:
- Committing `.env`, `.key`, `.pem`, or credential files
- `debugger` statements
- Merge conflict markers
- Files over 500KB

It warns on `console.log/debug/warn` statements (add `// keep` to bypass).
45 changes: 45 additions & 0 deletions docs/commits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Commit Conventions

ViewStack enforces commit message conventions via a git hook.

## Format

```
Prefix: Short description in imperative mood

Optional body explaining why (not what).
```

## Prefixes

| Prefix | When to Use | Example |
|--------|-------------|---------|
| `Add:` | New feature or file | `Add: indicator comparison chart` |
| `Fix:` | Bug fix | `Fix: loading state not showing on slow networks` |
| `Update:` | Enhancement to existing feature | `Update: improve mobile table layout` |
| `Refactor:` | Code restructuring (no behavior change) | `Refactor: extract DataTable component` |
| `Docs:` | Documentation | `Docs: add API client usage guide` |
| `Test:` | Tests | `Test: add StatCard rendering tests` |
| `CI:` | CI/CD pipeline | `CI: add build verification to workflow` |
| `Chore:` | Maintenance | `Chore: update dependencies` |
| `Translate:` | Translation/i18n | `Translate: add Hindi labels` |

## Rules

- Subject line should be under 72 characters
- Use imperative mood ("add", not "added" or "adds")
- Capitalize the first word after the prefix
- No period at the end of the subject line

## Examples

```
Add: budget trend visualization for scheme detail page

Shows allocated vs spent budget over fiscal years using a grouped
bar chart. Data comes from the budgets API endpoint.
```

```
Fix: silent error in Schemes page when sectors API fails
```
Loading
Loading