Interactive web application presenting the Global Ocean Observing System (GOOS) Status Report 2025. Built with React, TypeScript, and modern web technologies to deliver an engaging, multilingual experience showcasing ocean observing networks and their contributions to climate, operational services, and ocean health.
- π 30+ Custom Components - Modular architecture for data visualization, media galleries, and interactive content
- π¨ GOOS Design System - Complete color palette with 45 custom Tailwind colors
- π Multilingual Support - Full internationalization in English, Spanish, and French
- β‘οΈ Fast Performance - Vite build tool with Hot Module Replacement (HMR)
- π¬ Smooth Animations - GSAP-powered entrance effects and scroll triggers
- π Data Visualization - Interactive tables, stats panels, and network cards
- πΌοΈ Rich Media - Image galleries, video modals, and carousel components
- π± Fully Responsive - Mobile-first design adapting to all screen sizes
- React 18 - UI library with hooks and functional components
- TypeScript 5 - Type safety and enhanced developer experience
- Vite 5 - Lightning-fast build tool and dev server
- Tailwind CSS 3 - Utility-first styling with custom GOOS theme
- react-i18next 14 - Internationalization framework
- GSAP - Professional-grade animation library
- Embla Carousel - Smooth, performant carousels
- Roboto Fonts - Typography via @fontsource
- Node.js (v18 or higher recommended)
- npm or yarn package manager
# Clone the repository
git clone https://github.com/OceanOPS/oceanops-report-card.git
cd oceanops-report-card
# Install dependencies
npm install# Start development server
npm run devThe application will start at different URLs depending on your branch:
- staging or feature branches:
http://localhost:5173/(root deployment) - main:
http://localhost:5173/demos/report-card/(subdirectory deployment)
Both use the same code with asset() helper - only vite.config.ts differs.
# Type-check and build
npm run build
# Preview production build
npm run previewnpm run dev- Start development server with HMRnpm run build- Type-check with TypeScript and build for productionnpm run lint- Run ESLint on all TypeScript filesnpm run preview- Preview production build locally
Interactive component documentation is available via Storybook. It includes:
- π 30+ Component Stories - Complete documentation for all React components
- π¨ Figma Integration - Embedded Figma designs for each component
- π Live Examples - Interactive component variants and use cases
- π Design System - Complete GOOS color palette and typography reference
- πΌοΈ Design Prototypes - Interactive prototypes of the full report
# Navigate to docs folder
cd docs
# Install dependencies (first time only)
npm install
# Start Storybook
npm run storybookStorybook will start at http://localhost:6006
- 01. Introduction - Project overview, complete report layout, and credits
- 02. Design System - Figma designs and interactive prototypes
- 03. Foundation - Colors, typography, spacing, and icons
- 04. Brand - GOOS logo and partner logos
- 05. Components - All 30+ React components with Figma designs
- 06. Layout - Layout modules and carousels
Each component story includes:
- Embedded Figma design
- Interactive controls to test props
- Multiple variants and use cases
- Links to open designs directly in Figma
oceanops-report-card/
βββ docs/ # Storybook documentation (isolated)
β βββ .storybook/ # Storybook configuration
β βββ stories/ # Component stories with Figma embeds
β βββ package.json # Storybook dependencies
β βββ tailwind.config.js # Storybook-specific Tailwind config
βββ public/ # Static assets
β βββ backgrounds/ # Background images
β βββ icons/ # Network, physics, and biology icons
β βββ images/ # Content images
β βββ logos/ # Partner and organization logos
β βββ videos/ # Video files
βββ src/
β βββ components/ # 30+ React components
β βββ locales/ # Translation files (en, es, fr)
β βββ utils/ # Utility functions
β β βββ assets.ts # asset() helper for base URL resolution
β βββ App.tsx # Main application
β βββ main.tsx # Application entry point
β βββ i18n.ts # i18next configuration
β βββ index.css # Global styles with Tailwind
βββ tailwind.config.js # Tailwind + GOOS color configuration
βββ vite.config.ts # Vite configuration
βββ tsconfig.json # TypeScript configuration
The project uses a two-branch workflow:
feature-branches β staging (testing/preview) β main (production)
- staging - Default branch for development and testing (deployed to Netlify)
- main - Production branch (deployed to subdirectory)
Both branches use identical code with the asset() helper function for all asset paths. The only difference is the vite.config.ts configuration:
staging (vite.config.ts):
export default defineConfig({
plugins: [react()],
// No base path - deploys to root
})BASE_URL=/asset('/images/photo.jpg')β/images/photo.jpg- Deployed to:
https://oceanops-report-card.netlify.app/
main (vite.config.ts):
export default defineConfig({
plugins: [react()],
base: '/demos/report-card/',
})BASE_URL=/demos/report-card/asset('/images/photo.jpg')β/demos/report-card/images/photo.jpg- Deployed to:
https://oceanops.org/demos/report-card/
This approach allows seamless cherry-picking of commits between branches without manual path adjustments.
- Branch:
staging - URL: Deployed to root path
- Purpose: Testing and preview environment
- Branch:
main - URL: Deployed to
/demos/report-card/subdirectory - Purpose: Live production site
- Preloader - Loading screen with progress indicator
- CoverModule - Hero section with background media
- ContentModule - Flexible content sections
- Spacer - Consistent vertical spacing
- StatsGrid - 2Γ2 statistics grid
- DataTable - Configurable data tables
- IconTable - Tables with icons and legends
- DataCard - Individual data cards
- MapStatsPanel - Map/iframe with optional stats
- NetworkCard - Network information with ratings
- NetworkCarousel - Horizontal scrolling network cards
- EmergingNetworkCard - Media-rich emerging network cards
- EmergingNetworkCarousel - Carousel for emerging networks
- ImageGallery - Carousel with navigation
- VideoModal - YouTube and local video player
- ContentModal - Flexible modal overlay
- ImageGrid - Responsive image grids
- Button - Multi-variant button (link, video, modal)
- Tooltip - Hover tooltips
- LanguageSwitcher - Language toggle
The application supports three languages:
- π¬π§ English (default)
- πͺπΈ Spanish
- π«π· French
All user-facing text uses translation keys from src/locales/ JSON files.
- Update
src/locales/en.jsonwith new keys - Translate to Spanish in
src/locales/es.json - Translate to French in
src/locales/fr.json - Use keys in components via
useTranslation()hook
Custom Tailwind colors with 9 shades each (100-900):
- Blue (
goos-blue) - Primary brand color - Cyan (
goos-cyan) - Light blue accent - Orange (
goos-orange) - Attention and highlights - Green (
goos-green) - Success and environment - Gray (
goos-gray) - Neutral and text
Usage:
<div className="bg-goos-blue-700 text-white">
<h2 className="text-goos-orange-500">Title</h2>
</div>- Use TypeScript for all components
- Follow existing component patterns
- Use translation keys (never hardcode text)
- Implement responsive design (mobile-first)
- Add JSDoc comments to all components
- Create feature branch from
staging - Develop and test locally (use
asset()for all asset paths) - Create PR to
stagingfor testing - After approval, cherry-pick commits to
main(no manual edits needed!)
Note: Since both branches use asset(), cherry-picking commits from staging to main requires no manual path adjustments. Only vite.config.ts differs between branches.
Use clear, descriptive commit messages:
git commit -m "Add NetworkCarousel component with Embla integration"
git commit -m "Fix TypeScript errors in Button component"If port 5173 is busy, Vite will automatically use the next available port.
If you encounter import errors, ensure all dependencies are installed:
npm installRestart the dev server:
# Press Ctrl+C to stop
npm run devRun type-check before building:
npx tsc --noEmit
npm run build- Fork the repository
- Create your feature branch (
git checkout -b _featureName) - Commit your changes
- Push to the branch (
git push origin _featureName) - Open a Pull Request to
stagingbranch
Built with βοΈ React β’ β‘οΈ Vite β’ π· TypeScript β’ π¨ Tailwind CSS