Skip to content

Commit 97b1d0c

Browse files
Fix colors
1 parent daf74b4 commit 97b1d0c

5 files changed

Lines changed: 102 additions & 20 deletions

File tree

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# MWD WINS API Explorer
2+
3+
A web application for exploring water meter data from the Metropolitan Water District of Southern California (MWD). Browse agencies, search meters, view real-time flow data, and visualize historical usage with interactive charts.
4+
5+
## What is this?
6+
7+
The Metropolitan Water District of Southern California provides public access to water delivery data through their WINS (Water Information System) API. This explorer makes that data accessible through an intuitive interface, allowing anyone to:
8+
9+
- **Browse member agencies** - View the 27 member agencies and their sub-agencies that receive water from MWD
10+
- **Explore meters** - Search through service connections and meters across Southern California
11+
- **View real-time data** - See current flow rates for any meter
12+
- **Analyze historical data** - Visualize 15-minute interval flow and volume data with interactive charts
13+
- **Test the API** - Use the built-in playground to construct and test API calls
14+
15+
## Features
16+
17+
### Dashboard
18+
Overview of the system with quick stats on agencies, meters, and active connections.
19+
20+
### Agency Explorer
21+
Browse all member agencies and retail agencies. View their service connections, filter by status (active/retired), and see connection details like capacity, feeder, and reading type.
22+
23+
### Meter Explorer
24+
Search for specific meters, view detailed connection information, and analyze interval data with:
25+
- **Flow charts** - Line charts showing flow rate (CFS) over time
26+
- **Volume charts** - Bar charts showing water volume (acre-feet) per interval
27+
- **Cumulative charts** - Area charts showing total volume delivered over a date range
28+
- **Data export** - Download data as CSV or JSON
29+
30+
### API Playground
31+
Test API endpoints directly, view responses, and generate code snippets for your own applications.
32+
33+
## Data Source
34+
35+
All data is provided by the **Metropolitan Water District of Southern California** through their public WINS API.
36+
37+
- **API Documentation**: [https://webservices.mwdsc.org/wins/Public/Help](https://webservices.mwdsc.org/wins/Public/Help)
38+
- **Data Provider**: Metropolitan Water District of Southern California
39+
40+
The WINS API provides access to:
41+
- Member and sub-agency information
42+
- Service connection details
43+
- Real-time flow readings
44+
- Historical interval data (15-minute intervals)
45+
- Meter readings
46+
47+
## Technology
48+
49+
Built with:
50+
- [React](https://react.dev/) - UI framework
51+
- [TypeScript](https://www.typescriptlang.org/) - Type safety
52+
- [Vite](https://vitejs.dev/) - Build tool
53+
- [Tailwind CSS](https://tailwindcss.com/) - Styling
54+
- [React Query](https://tanstack.com/query) - Data fetching and caching
55+
- [Recharts](https://recharts.org/) - Charts and visualizations
56+
- [React Router](https://reactrouter.com/) - Navigation
57+
58+
## Development
59+
60+
```bash
61+
# Install dependencies
62+
npm install
63+
64+
# Start development server
65+
npm run dev
66+
67+
# Build for production
68+
npm run build
69+
70+
# Preview production build
71+
npm run preview
72+
```
73+
74+
## License
75+
76+
This project is open source. The data displayed is public information provided by MWD.
77+
78+
---
79+
80+
*This application is not affiliated with or endorsed by the Metropolitan Water District of Southern California. It is an independent tool for exploring publicly available data.*

src/components/common/Header.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ export function Header() {
1111
const location = useLocation()
1212

1313
return (
14-
<header className="bg-mwd-blue-800 border-b border-mwd-blue-700 sticky top-0 z-50">
14+
<header className="sticky top-0 z-50 border-b border-mwd-blue-900" style={{ backgroundColor: '#164876' }}>
1515
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1616
<div className="flex items-center justify-between h-16">
1717
<Link to="/" className="flex items-center gap-3">
1818
<svg
19-
className="h-8 w-8 text-mwd-blue-400"
19+
className="h-8 w-8 text-white"
2020
viewBox="0 0 24 24"
2121
fill="currentColor"
2222
>
@@ -36,8 +36,8 @@ export function Header() {
3636
to={item.path}
3737
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
3838
isActive
39-
? 'bg-mwd-blue-400 text-mwd-blue-900'
40-
: 'text-mwd-blue-200 hover:text-white hover:bg-mwd-blue-700'
39+
? 'bg-white text-mwd-blue-800'
40+
: 'text-white/80 hover:text-white hover:bg-white/10'
4141
}`}
4242
>
4343
{item.name}
@@ -50,7 +50,7 @@ export function Header() {
5050
href="https://webservices.mwdsc.org/wins/Public/Help"
5151
target="_blank"
5252
rel="noopener noreferrer"
53-
className="hidden sm:flex items-center gap-1 text-sm text-mwd-blue-300 hover:text-white"
53+
className="hidden sm:flex items-center gap-1 text-sm text-white/80 hover:text-white"
5454
>
5555
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
5656
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
@@ -61,7 +61,7 @@ export function Header() {
6161
</div>
6262

6363
{/* Mobile navigation */}
64-
<nav className="md:hidden border-t border-mwd-blue-700 px-4 py-2 flex gap-1 overflow-x-auto">
64+
<nav className="md:hidden border-t border-mwd-blue-900 px-4 py-2 flex gap-1 overflow-x-auto" style={{ backgroundColor: '#164876' }}>
6565
{navigation.map((item) => {
6666
const isActive = location.pathname === item.path
6767
return (
@@ -70,8 +70,8 @@ export function Header() {
7070
to={item.path}
7171
className={`px-3 py-1.5 rounded-lg text-sm font-medium whitespace-nowrap transition-colors ${
7272
isActive
73-
? 'bg-mwd-blue-400 text-mwd-blue-900'
74-
: 'text-mwd-blue-200 hover:text-white hover:bg-mwd-blue-700'
73+
? 'bg-white text-mwd-blue-800'
74+
: 'text-white/80 hover:text-white hover:bg-white/10'
7575
}`}
7676
>
7777
{item.name}

src/components/common/StatCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function StatCard({ label, value, icon, subtext, trend }: StatCardProps)
1717
<div className="flex items-start justify-between">
1818
<div>
1919
<p className="text-sm font-medium text-mwd-blue-600">{label}</p>
20-
<p className="mt-1 text-2xl font-semibold text-mwd-blue-800">{value}</p>
20+
<p className="mt-1 text-2xl font-semibold" style={{ color: '#2e74a8' }}>{value}</p>
2121
{subtext && <p className="mt-1 text-sm text-mwd-blue-500">{subtext}</p>}
2222
{trend && (
2323
<p
@@ -31,7 +31,7 @@ export function StatCard({ label, value, icon, subtext, trend }: StatCardProps)
3131
)}
3232
</div>
3333
{icon && (
34-
<div className="p-2 bg-lavender-100 rounded-lg text-mwd-blue-800">
34+
<div className="p-2 rounded-lg" style={{ backgroundColor: '#c4ddf0', color: '#2e74a8' }}>
3535
{icon}
3636
</div>
3737
)}

src/pages/ApiPlayground.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,10 @@ print(data)`
185185
onClick={() => setCodeLanguage(lang)}
186186
className={`px-3 py-1 text-xs font-medium rounded ${
187187
codeLanguage === lang
188-
? 'bg-mwd-blue-800 text-white'
188+
? 'text-white'
189189
: 'bg-lavender-100 text-mwd-blue-700 hover:bg-lavender-200'
190190
}`}
191+
style={codeLanguage === lang ? { backgroundColor: '#164876' } : undefined}
191192
>
192193
{lang === 'javascript' ? 'JS' : lang === 'python' ? 'Python' : 'cURL'}
193194
</button>

src/pages/MeterExplorer.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,16 @@ export function MeterExplorer() {
264264
{/* Connection Details & Current Flow */}
265265
<div className="card p-4">
266266
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
267-
<div className="bg-mwd-blue-800 rounded-lg p-3">
268-
<p className="text-xs font-medium text-white/80">Current Flow</p>
267+
<div className="bg-lavender-100 rounded-lg p-3 border-2 border-mwd-blue-400">
268+
<p className="text-xs font-medium text-mwd-blue-600">Current Flow</p>
269269
{flowLoading ? (
270-
<p className="text-xl font-bold text-white">...</p>
270+
<p className="text-xl font-bold" style={{ color: '#2e74a8' }}>...</p>
271271
) : currentFlow && currentFlow[0] ? (
272-
<p className="text-xl font-bold text-white">
272+
<p className="text-xl font-bold" style={{ color: '#2e74a8' }}>
273273
{currentFlow[0].Flow} <span className="text-xs font-normal">CFS</span>
274274
</p>
275275
) : (
276-
<p className="text-xl font-bold text-white">N/A</p>
276+
<p className="text-xl font-bold" style={{ color: '#2e74a8' }}>N/A</p>
277277
)}
278278
</div>
279279
{connectionInfo && (
@@ -413,9 +413,10 @@ export function MeterExplorer() {
413413
onClick={() => setChartType(type)}
414414
className={`px-4 py-2 text-sm font-medium rounded-lg transition-colors ${
415415
chartType === type
416-
? 'bg-mwd-blue-800 text-white'
416+
? 'text-white'
417417
: 'bg-lavender-100 text-mwd-blue-700 hover:bg-lavender-200'
418418
}`}
419+
style={chartType === type ? { backgroundColor: '#164876' } : undefined}
419420
>
420421
{type === 'flow' ? 'Flow' : type === 'volume' ? 'Volume' : 'Cumulative'}
421422
</button>
@@ -440,7 +441,7 @@ export function MeterExplorer() {
440441
<YAxis tick={{ fontSize: 12 }} tickLine={false} axisLine={false} label={{ value: 'Flow (CFS)', angle: -90, position: 'insideLeft' }} />
441442
<Tooltip contentStyle={{ backgroundColor: 'white', border: '1px solid #e5e7eb', borderRadius: '8px' }} />
442443
<Legend />
443-
<Line type="monotone" dataKey="Flow" stroke="#2c3c5b" strokeWidth={2} dot={false} name="Flow (CFS)" />
444+
<Line type="monotone" dataKey="Flow" stroke="#2e74a8" strokeWidth={2} dot={false} name="Flow (CFS)" />
444445
</LineChart>
445446
) : chartType === 'volume' ? (
446447
<BarChart data={chartData}>
@@ -449,7 +450,7 @@ export function MeterExplorer() {
449450
<YAxis tick={{ fontSize: 12 }} tickLine={false} axisLine={false} label={{ value: 'Volume (AF)', angle: -90, position: 'insideLeft' }} />
450451
<Tooltip contentStyle={{ backgroundColor: 'white', border: '1px solid #e5e7eb', borderRadius: '8px' }} />
451452
<Legend />
452-
<Bar dataKey="Volume" fill="#82aed6" name="Volume (AF)" />
453+
<Bar dataKey="Volume" fill="#4a90c4" name="Volume (AF)" />
453454
</BarChart>
454455
) : (
455456
<AreaChart data={chartData}>
@@ -458,7 +459,7 @@ export function MeterExplorer() {
458459
<YAxis tick={{ fontSize: 12 }} tickLine={false} axisLine={false} label={{ value: 'Cumulative Volume (AF)', angle: -90, position: 'insideLeft' }} />
459460
<Tooltip contentStyle={{ backgroundColor: 'white', border: '1px solid #e5e7eb', borderRadius: '8px' }} />
460461
<Legend />
461-
<Area type="monotone" dataKey="cumulativeVolume" stroke="#2c3c5b" fill="#82aed6" name="Cumulative Volume (AF)" />
462+
<Area type="monotone" dataKey="cumulativeVolume" stroke="#2e74a8" fill="#4a90c4" fillOpacity={0.6} name="Cumulative Volume (AF)" />
462463
</AreaChart>
463464
)}
464465
</ResponsiveContainer>

0 commit comments

Comments
 (0)