{"id":46638263,"url":"https://github.com/tetherto/miningos-app-ui","last_synced_at":"2026-03-08T02:13:21.763Z","repository":{"id":336194842,"uuid":"1129676215","full_name":"tetherto/miningos-app-ui","owner":"tetherto","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-26T12:35:31.000Z","size":5462,"stargazers_count":6,"open_issues_count":2,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-26T19:17:35.289Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tetherto.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-07T12:28:38.000Z","updated_at":"2026-02-26T12:35:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tetherto/miningos-app-ui","commit_stats":null,"previous_names":["tetherto/miningos-app-ui"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tetherto/miningos-app-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fminingos-app-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fminingos-app-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fminingos-app-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fminingos-app-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tetherto","download_url":"https://codeload.github.com/tetherto/miningos-app-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fminingos-app-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30242406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:58:18.660Z","status":"online","status_checked_at":"2026-03-08T02:00:06.215Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-08T02:13:21.122Z","updated_at":"2026-03-08T02:13:21.748Z","avatar_url":"https://github.com/tetherto.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# miningos-app-ui --- Mining OS App UI\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Architecture](#architecture)\n3. [Feature Flags](#feature-flags)\n4. [Feature Configs](#feature-configs)\n5. [Mempool Data Integration via API](mempool-data-integration-via-api)\n6. [Development Setup](#development-setup)\n7. [Sentry Error Tracking](#sentry-error-tracking)\n8. [Logger Service](#logger-service)\n9. [Testing](#testing)\n10. [Code Quality](#code-quality)\n11. [Architecture Documentation](#architecture-documentation)\n12. [Project Structure](#project-structure)\n13. [Key Technologies](key-technologies)\n14. [Environment Variables](#environment-variables)\n\n## Overview\n\n**miningos-app-ui** is a comprehensive React-based dashboard for monitoring and managing Bitcoin mining operations. It serves as the primary user interface for MiningOS, consuming data from multiple specialized Node.js workers to provide real-time visibility and control over mining facilities, by consuming data from various backend workers through REST APIs.\n\n## Architecture\n\nThis application is a **data consumer and control interface** in a distributed mining management system:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                  MiningOS Infrastructure                    │\n│  (Miners, Containers, Sensors, Power Meters, etc.)          │\n└────────────────┬────────────────────────────────────────────┘\n                 │\n    ┌────────────┴────────────────┐\n    │   MiningOS Worker Layer     │\n    │  (Node.js RPC Workers)      │\n    ├─────────────────────────────┤\n    │ • miningos-wrk-ext-mempool  │ ← Bitcoin network data\n    │ • miningos-wrk-sensor       │ ← Temperature sensors\n    │ • miningos-wrk-container    │ ← Mining containers\n    │ • miningos-wrk-miner        │ ← Individual miners\n    │ • miningos-wrk-powermeter   │ ← Power consumption\n    └────────────┬────────────────┘\n                 │\n         ┌───────┴────────┐\n         │  API Gateway   │\n         │  (/auth/*)     │\n         └───────┬────────┘\n                 │\n    ┌────────────┴──────────────┐\n    │   miningos-app-ui         │\n    │  (React + Redux + RTK)    │\n    └───────────────────────────┘\n```\n\n### Related Projects\n\n#### Parent/Sibling Workers\n\n- **miningos-tpl-wrk-thing** - Base template for all device workers, provides core RPC infrastructure, thing management, and data collection patterns\n- **miningos-wrk-ext-mempool** - Bitcoin network statistics worker (this README documents its integration)\n- **miningos-wrk-sensor** - Temperature sensor data collection\n- **miningos-wrk-container** - Mining container management (Bitdeer, MicroBT, Antspace)\n- **miningos-wrk-miner** - Individual miner control and monitoring\n- **miningos-wrk-powermeter** - Power consumption tracking\n\n#### Shared Libraries\n\n- **miningos-lib-stats** - Statistics aggregation and calculation utilities\n- **miningos-lib-utils** - Common utility functions\n- **hp-svc-facs-net** - Hyperswarm RPC networking layer\n- **hp-svc-facs-store** - Hyperbee distributed storage layer\n\n### API Gateway\n\n- Base path: `${VITE_API_BASE_URL}auth` (typically `/auth/*` in production)\n\n## Feature Flags\n\nFeature flags are release-specific controls used to enable or disable features dynamically without deploying new code. They allow teams to gradually roll out new features and test them in production before making them widely available.\n\n- **Purpose**: Hide unstable or experimental features until they are ready\n- **Usage**: Enabled manually by passing feature names as comma-separated values in the URL query parameters (e.g., `?features=featureA,featureB`)\n- **Scope**: Limited to the current release and can be toggled on/off as needed\n\n### Enabling Features\n\nTo enable features, use the `features` parameter in your URL.\n\n#### Example\n\nEnable both `reporting` and `poolStats`:\n\n```\nhttp://localhost:3030/?features=reporting,poolStats\n```\n\n#### Current Feature Flags\n\n- `userManagement` - User administration interface\n- `energyProvision` - Energy provisioning controls\n- `admeStatsEnabled` - Advanced mining efficiency statistics\n- `minersOverview` - Comprehensive miner fleet view\n- `inventory` - Inventory management system\n- `alertsHistoricalLogEnabled` - Historical alert analysis\n- `spotPriceSettings` - Spot price configuration\n- `weeklyForecast` - Predictive analytics dashboard\n- `oceanLuck` - Mining luck indicator\n\n## Feature Configs\n\nFeature configs are environment-specific settings that determine the behavior of a feature based on the deployment environment (e.g., development, staging, production sites).\n\n- **Purpose**: Control feature availability or configuration based on the environment\n- **Usage**: Configured in backend configuration files (dashboard-app-node repo)\n- **Scope**: Persistent across releases and varies by environment\n\n#### Current Feature Configs\n\n- `isOneMinItvEnabled` - Enable 1-minute polling intervals\n- `totalTransformerConsumptionHeader` - Show transformer consumption in header\n- `poolStats` - Display mining pool statistics\n- `totalSystemConsumptionHeader` - Show total system consumption in header\n- `isStaticIpAssignment` - Use static IP assignment mode\n- `comments` - Enable device commenting system\n- `powerModeTimeline` - Display power mode timeline chart\n- `totalSystemConsumptionChart` - Show system consumption chart on dashboard\n- `showMinerConsumptionDashboard` - Display miner-level consumption data\n- `powerAvailable` - Show available power metrics\n- `reporting` - **[Default: false]** Enable the entire Reports section in the sidebar, including all Operations Reports (Dashboard, Hashrate, Energy, Efficiency, Miners) and Financial Reports (Revenue Summary, Cost Summary, EBITDA, Subsidy Fee, Hash Balance, Energy Balance, Cost Input). When disabled, the Reports menu item and all its sub-items are hidden from navigation\n- `settings` - Enable settings management\n- `containerCharts` - **[Default: false]** Display container analytics line charts at `/operations/mining/container-charts`. When disabled, hides the menu item and shows \"Feature not enabled\" message if accessed directly\n- `isMultiSiteModeEnabled` - **[Default: false]** Enable multi-site mode with cross-site reporting and analytics. When `false` or `undefined`, the app runs in single-site mode with standard navigation. Multi-site routes (`/dashboard`, `/revenue-and-cost`, `/site-operations`, `/site-reports`) are completely excluded and the multi-site router is not loaded\n\n### Backend Configuration Example\n\nTo configure feature configs in the backend (dashboard-app-node repo), set them in your environment-specific config file:\n\n```json\n{\n  \"featureConfig\": {\n    \"reporting\": false,\n    \"settings\": true,\n    \"comments\": false,\n    \"containerCharts\": false,\n    \"isMultiSiteModeEnabled\": false,\n    \"poolStats\": true,\n    \"powerModeTimeline\": true\n  }\n}\n```\n\n**Important**: Features default to `false` when not explicitly set. To enable a feature, you must explicitly set it to `true` in the backend configuration.\n\n## Mempool Data Integration via API\n\nThe application consumes real-time Bitcoin network statistics from the **miningos-wrk-ext-mempool** worker to support mining profitability calculations and operational decisions.\n\n### Data Source\n\n**Worker**: `miningos-wrk-ext-mempool`  \n**API Endpoint**: `/auth/ext-data?type=mempool` TODO: verify\n**Update Frequency**: Every 30 minutes (configurable)  \n**Data Storage**: Hyperbee distributed database with 180-day retention for hashrate history\n\n### Available Metrics\n\nThe mempool worker provides the following data structure:\n\n```typescript\ninterface MempoolData {\n  // Bitcoin Price\n  currentPrice: number // Current BTC price in USD\n  priceChange24Hrs: number // 24-hour price change percentage\n\n  // Network Status\n  blockHeight: number // Current Bitcoin block height\n  currentHashrate: number // Current network hashrate (H/s)\n  currentDifficulty: number // Current mining difficulty\n\n  // Difficulty Adjustment\n  adjustments: {\n    progressToDifficulty: number // Progress to next difficulty adjustment (%)\n    nextAdjustmentTs: number // Timestamp of next adjustment\n    nextAdjustmentExp: number // Expected difficulty change (%)\n    prevAdjustment: number // Previous adjustment (%)\n    avgBlockTime: number // Average block time (minutes)\n  }\n\n  // Block Rewards (averaged over time periods)\n  blockRewardAvgs: {\n    '24h': number // 24-hour average reward (BTC)\n    '3d': number // 3-day average reward (BTC)\n    '1w': number // 1-week average reward (BTC)\n    '1m': number // 1-month average reward (BTC)\n    '3m': number // 3-month average reward (BTC)\n    '6m': number // 6-month average reward (BTC)\n    '1y': number // 1-year average reward (BTC)\n    '2y': number // 2-year average reward (BTC)\n    '3y': number // 3-year average reward (BTC)\n  }\n\n  // Transaction Fees\n  transactionFees: {\n    fastest: number // Sat/vB for fastest confirmation\n    halfHour: number // Sat/vB for ~30min confirmation\n    hour: number // Sat/vB for ~1hr confirmation\n  }\n}\n```\n\n**Note**: The worker also stores historical hashrate data in Hyperbee with tags `'stat-30m'`, `'stat-3h'`, and `'stat-1D'`, but this historical data is not currently exposed through the UI's API query interface.\n\n### Usage in Application\n\n#### Basic Query\n\n```javascript\nimport { useGetExtDataQuery } from '@/app/services/api'\n\nconst { data: mempoolData } = useGetExtDataQuery({ type: 'mempool' })\n\n// Access data (returns array of data objects)\nconst bitcoinData = mempoolData?.[0]?.[0]\n\n// Extract specific metrics\nconst btcPrice = bitcoinData?.currentPrice\nconst difficulty = bitcoinData?.currentDifficulty\nconst networkHashrate = bitcoinData?.currentHashrate\nconst blockRewards = bitcoinData?.blockRewardAvgs\nconst txFees = bitcoinData?.transactionFees\n```\n\n### Components Using Mempool Data\n\nThe following components and features consume mempool worker data:\n\n- **Bitcoin Network Data Report** (`/reporting/bitcoin-network-data`) - Comprehensive view displaying:\n  - Current BTC price and 24-hour price change\n  - Block height and network hashrate\n  - Difficulty adjustment metrics and progress gauge\n  - Block reward averages (displays 24h, 1w, 1m periods)\n  - Transaction fee recommendations (fastest, 30min, 1hr)\n\n- **Weekly Forecast** (`/reporting/weekly-forecast`) - Uses network data for predictive analytics and profitability forecasting\n\n- **Revenue Calculations** - Block reward averages and transaction fees are used in profitability calculations through hooks like `useRevenueNextHour`\n\n- **Mine/Stop-Mine Decision Engine** - Network conditions (indirectly via revenue calculations) inform operational decisions displayed in the Dashboard\n\n### Data Flow\n\n```\n┌─────────────────────┐\n│  mempool.space API  │\n│  (Public Bitcoin    │\n│   Network Data)     │\n└──────────┬──────────┘\n           │ Poll every 30min\n           │\n┌──────────▼─────────────────────────────────────────────┐\n│  miningos-wrk-ext-mempool                              │\n│  • Fetches prices, hashrate, difficulty, fees          │\n│  • Calculates rolling averages                         │\n│  • Stores in Hyperbee (180-day retention)              │\n│  • Exposes via RPC: getWrkExtData()                    │\n└──────────┬─────────────────────────────────────────────┘\n           │ RPC Communication\n           │\n┌──────────▼───────────┐\n│   API Gateway        │\n│   /auth/ext-data     │\n└──────────┬───────────┘\n           │ HTTP REST\n           │\n┌──────────▼───────────────────────────────────────────────┐\n│  miningos-app-ui                                         │\n│  • RTK Query: useGetExtDataQuery({ type: 'mempool' })    │\n│  • Redux store caching                                   │\n│  • Bitcoin Network Data Report component                 │\n│  • Revenue calculation hooks                             │\n└──────────────────────────────────────────────────────────┘\n```\n\n### Implementation Details\n\n**File Locations**:\n\n- Worker: `miningos-wrk-ext-mempool/workers/rack.mempool.ext.wrk.js`\n- API Integration: `miningos-wrk-ext-mempool/workers/lib/mempool.api.js`\n- UI Hook: `src/app/services/api.js` (RTK Query endpoint)\n\n**Backend Capabilities**:\nThe mempool worker provides all 9 time periods for block reward averages (`'24h'`, `'3d'`, `'1w'`, `'1m'`, `'3m'`, `'6m'`, `'1y'`, `'2y'`, `'3y'`), though the UI currently displays only the first three periods in the Bitcoin Network Data Report.\n\n**Polling Intervals**:\n\n- Real-time data fetch: Every 30 minutes (configurable via `conf.mempool.dataFetchIntervalMs`)\n- Historical data fetch: Every 12 hours (configurable via `conf.mempool.historicalDataFetchIntervalMs`)\n\n## Development Setup\n\n### Prerequisites\n\n- Node.js \u003e= 20\n- npm \u003e= 10\n\n### Installation\n\n```bash\nnpm install\n```\n\n### Running Locally\n\n```bash\nnpm start\n```\n\nApplication will be available at `http://localhost:3030`\n\n### Demo Mode\n\nRun the application using mock data (no backend required):\n\n```bash\n# Start in demo mode with mock data\nnpm run start:demo\n\n# Capture mock data while using the app\nnpm run start:demo-capture\n\n# Build for demo/offline deployment\nnpm run build:demo\n\n# Preview demo build\nnpm run preview:demo\n```\n\n### Building for Production\n\n```bash\nnpm run build\n```\n\n## Sentry Error Tracking\n\nTo enable Sentry error tracking, create a `.sentryclirc` file from the example:\n\n```bash\nnpm run sentry:create-config\n```\n\nAdd your Sentry auth token to the configuration file.\n\n## Logger Service\n\nThe logger service is a centralized logging system that collects and stores logs from various components of the application.\n\nTo enable development mode logging:\n\n```javascript\nlocalStorage.setItem('features', JSON.stringify({ isDevelopment: true }))\n```\n\nIn production, logs are automatically sent to Sentry.\n\n## Testing\n\n```bash\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Run tests in watch mode\nnpm run test:watch\n```\n\n## Code Quality\n\n```bash\n# Lint code\nnpm run lint\n\n# Fix lint issues\nnpm run lint:fix\n\n# Format code with Prettier\nnpm run prettier:fix\n```\n\n## Architecture Documentation\n\nFor detailed information about the application architecture, features, and component organization, see:\n\n- **[FEATURES_ARCHITECTURE.md](docs/FEATURES_ARCHITECTURE.md)** - Comprehensive feature documentation, state management, and file organization\n- **[README_ContainerSettings.md](docs/README_ContainerSettings.md)** - Container settings API and threshold configuration guide\n\n## Project Structure\n\n```\nsrc/\n├── app/                          # Redux store and API services\n│   ├── services/                 # RTK Query API definitions\n│   │   ├── api.js               # Main API service\n│   │   ├── websocket.js         # WebSocket service\n│   │   └── logger.js            # Logging service\n│   ├── slices/                  # Redux state slices\n│   └── utils/                   # State management utilities\n├── Components/                   # Reusable UI components (77+)\n├── Views/                       # Page-level components (23+)\n├── MultiSiteViews/              # Multi-site specific views\n├── hooks/                       # Custom React hooks (70+)\n├── constants/                   # Application constants\n├── router/                      # Routing configuration\n└── Theme/                       # Styling and theming\n```\n\n## Key Technologies\n\n- **React 19** - UI framework\n- **Redux Toolkit** - State management\n- **RTK Query** - API integration and caching\n- **Ant Design** - UI component library\n- **styled-components** - CSS-in-JS styling\n- **Chart.js** - Data visualization\n- **React Router** - Client-side routing\n\n## Environment Variables\n\n### Core Configuration\n\n```bash\nVITE_API_BASE_URL=http://localhost:8080/  # API gateway URL\n```\n\n### Mock Data System\n\nThe application includes a mock data system for development and testing purposes, allowing you to capture and replay API responses without requiring a live backend.\n\n#### `VITE_SAVE_MOCKDATA`\n\nEnables capturing of all XHR request arguments and their corresponding responses. When enabled, all API interactions are stored in `window.__mockdata` for later use.\n\n**_Setup_**\n\n1. Start the application normally (`npm run start`) and login\n2. Stop the application. This would save the credentials in your browser which will be later used by the demo capture\n\n**Quick Start:**\n\n```bash\n# 1. Start capture mode\nnpm run start:demo-capture\n\n# 2. Navigate through the app (click pages you want to capture)\n#    - Visit all containers, tabs, reports, etc.\n#    - Avoid full page refreshes (clears captured data)\n\n# 3. Open browser DevTools console (F12) and copy the data:\ncopy(window.__mockdata)\n\n# 4. Create a new file called mockdata-raw.json in the project root\n#    and paste the copied JSON data into it\n\n# 5. Run the sanitization script (uses mockdata-raw.json by default):\nnpm run sanitize-mockdata\n\n# 6. Test with mock data:\nnpm run start:demo\n```\n\n**What happens automatically:**\n\n- ✅ Sanitizes sensitive data (tokens, emails, JWT)\n- ✅ Splits data by feature into organized files:\n  - `src/mockdata/base.json` - Feature config, user info\n  - `src/mockdata/containers.json` - Container data\n  - `src/mockdata/financial.json` - Financial reports\n  - `src/mockdata/operations.json` - Mining operations\n  - `src/mockdata/other.json` - Everything else\n- ✅ Merges with existing files (keeps old data, adds/updates new)\n- ✅ Auto-generates `src/mockdata/index.ts` to merge all files\n\n**Advanced Options:**\n\n```bash\n# Use custom input file\nnpm run sanitize-mockdata my-capture.json\n\n# Save to single file instead of splitting (legacy)\nnpm run sanitize-mockdata -- --no-split\n\n# Save to specific split file\nnpm run sanitize-mockdata -- --split containers\n```\n\n**Incremental Updates:**\n\nWhen you fix a bug and only need to update specific pages:\n\n```bash\n# 1. Start capture mode\nnpm run start:demo-capture\n\n# 2. Visit ONLY the pages you fixed (e.g., Energy Balance)\n\n# 3. Copy and save to mockdata-raw.json\ncopy(window.__mockdata)\n\n# 4. Run sanitization (merges automatically, keeps all old data)\nnpm run sanitize-mockdata\n```\n\n**How Auto-Split Works:**\n\nThe script automatically categorizes data by URL patterns:\n\n- `base.json` - Feature config, user, auth\n- `containers.json` - Any key with \"container\"\n- `financial.json` - Keys with \"financial\", \"revenue\", \"cost\", \"energy\"\n- `operations.json` - Keys with \"operations\", \"mining\", \"miner\"\n- `alerts.json` - Keys with \"alert\"\n- `inventory.json` - Keys with \"inventory\"\n- `pools.json` - Keys with \"pool\"\n- `comments.json` - Keys with \"comment\"\n- `settings.json` - Keys with \"setting\"\n- `other.json` - Everything else\n\n**Troubleshooting:**\n\n- **\"No data\" on a page in demo mode**: The page wasn't visited during capture. Visit it with `npm run start:demo-capture` and run sanitization again.\n- **Data seems old after merge**: The merge keeps old data for keys you didn't update. Visit the specific page again to update its data.\n- **Want to start fresh**: Delete `src/mockdata/` folder and do a full capture.\n- **If the demo or demo capture mode infinitely loops**: Follow the setup steps again before running the demo or demo capture again\n\n**Security Note:**\n\nThe sanitization script automatically removes:\n\n- **API tokens**: `pub:api:TOKEN-123-roles:*` → `pub:api:SANITIZED_TOKEN-123-roles:*`\n- **Email addresses** → `mail@example.com`\n- **JWT Bearer tokens** → `Bearer SANITIZED_JWT_TOKEN`\n- **API keys** → `SANITIZED_API_KEY`\n- **Location/Site names**: `Test-1`, `Test-2`, etc. → `Site A`, `Country A`\n- **IP addresses**: `10.0.1.5` → `192.168.1.1`\n- **MAC addresses**: `00:1A:2B:3C:4D:5E` → `00:00:00:00:00:00`\n- **Phone numbers** (in phone/tel/mobile fields) → `+1-555-0100`\n\n⚠️ Always review sanitized files before committing to ensure no sensitive data remains.\n\n#### `VITE_USE_MOCKDATA`\n\nEnables the application to use mock data from `src/mockdata.ts` instead of making real XHR requests to the backend.\n\n**Usage:**\n\n```bash\nVITE_USE_MOCKDATA=true npm start\n```\n\nThis is useful for:\n\n- Frontend development without backend dependencies\n- Consistent testing scenarios\n- Demo environments\n- Offline development\n\n#### Using Mock Data Flags in Code\n\nImport the constants from `api.utils`:\n\n```typescript\nimport { isUseMockdataEnabled, isSaveMockdataEnabled, isDemoMode } from '@/app/services/api.utils'\n\n// Disable features in demo mode\n\u003cButton disabled={isDemoMode}\u003eExport Data\u003c/Button\u003e\n\n// Check specific flags\nif (isUseMockdataEnabled) {\n  // Using mock data\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fminingos-app-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftetherto%2Fminingos-app-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fminingos-app-ui/lists"}