{"id":14956703,"url":"https://github.com/wildaid/o-fish-web","last_synced_at":"2025-10-24T10:30:52.545Z","repository":{"id":37093703,"uuid":"268621621","full_name":"WildAid/o-fish-web","owner":"WildAid","description":"Web application for the Officer's Fishery Information Sharing Hub (O-FISH). The web app allows agencies to gain insights from the aggregated information gathered during a routine vessel inspection (submitted via the web app).","archived":false,"fork":false,"pushed_at":"2022-09-12T07:29:15.000Z","size":1332,"stargazers_count":32,"open_issues_count":109,"forks_count":40,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-29T09:44:54.963Z","etag":null,"topics":["charts","dataviz","hacktoberfest","hacktoberfest2020","hacktoberfest2021","mongodb","mongodb-atlas","mongodb-database","mongodb-realm","mongodb-stitch","non-profit","nonprofit","react","wildaid"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/WildAid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-01T20:10:24.000Z","updated_at":"2024-10-11T21:04:25.000Z","dependencies_parsed_at":"2022-06-24T13:47:23.935Z","dependency_job_id":null,"html_url":"https://github.com/WildAid/o-fish-web","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WildAid%2Fo-fish-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WildAid%2Fo-fish-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WildAid%2Fo-fish-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WildAid%2Fo-fish-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WildAid","download_url":"https://codeload.github.com/WildAid/o-fish-web/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237950796,"owners_count":19392666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["charts","dataviz","hacktoberfest","hacktoberfest2020","hacktoberfest2021","mongodb","mongodb-atlas","mongodb-database","mongodb-realm","mongodb-stitch","non-profit","nonprofit","react","wildaid"],"created_at":"2024-09-24T13:13:22.564Z","updated_at":"2025-10-24T10:30:51.846Z","avatar_url":"https://github.com/WildAid.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WildAid O-FISH Web App\n\nThe [WildAid Marine Program](https://marine.wildaid.org/) works to protect vulnerable marine environments.\n\nO-FISH (Officer Fishery Information Sharing Hub) is a multi-platform application that enables officers to browse and record boarding report data from their mobile devices.\n\nDevelopers are expected to follow the \u003cA HREF=\"https://www.mongodb.com/community-code-of-conduct\"\u003eMongoDB Community Code of Conduct\u003c/A\u003e guidelines.\n\nThis repo implements the O-FISH web app.\n\nThe details behind the data architecture, schema, and partitioning strategy are described in [Realm Data and Partitioning Strategy Behind the WildAid O-FISH Mobile Apps](https://developer.mongodb.com/how-to/realm-data-architecture-ofish-app).\n\nDetails on installing all applications making up the solution can be found [here](http://wildaid.github.io/).\n\n## Prerequisites\n\nThis is the Web app for O-FISH. To build and use the app, you must [use the sandbox realm-app-id](https://bit.ly/ofishsandbox) or [build your own foundation](http://wildaid.github.io/build).\n\nSetting up MongoDB Charts is optional, but places where charts should be will show errors if you don't - other functionality will be unaffected.\n\n`Node.js` must be installed.\n\n## Building and running the app:\n\n1. From the top-level directory (where this README file lives) run:\n`npm install`\n1. Copy `src/config.js.tmpl` to `src/config.js`\n1. Set your configuration data in `src/config.js` (leave the `chartId` values as they are if you haven't set up [MongoDB Charts](https://www.mongodb.com/products/charts) for the sample data - if you have then you can get the ids from the Charts UI):\n```js\nmodule.exports = {\n    appName: 'ofish-web',\n    realmServiceName: \"mongodb-atlas\",\n    realmAppId: 'wildaid-xxxxx',\n    database: 'wildaid',\n    chartsConfig: {\n      baseUrl: \"https://charts.mongodb.com/charts-wildaid-xxxxx\",\n      \"boardings\": {\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      },\n      \"boarding-compliance\":{\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      },\n      \"patrol-hours\":{\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      },\n      \"compliance-rate\":{\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      },\n      \"boardings-count-chart\":{\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      },\n      \"citations-and-warnings\":{\n        chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n      }\n    }\n  }\n```\n5. `npm start` (for local testing)\n1. `npm run build` (for deployment)\n\n\n## Code and architecture highlights:\n\nThis application uses React and is based on the React Services Architecture rather than Redux. If you are interested in why, read [You Might Not Need Redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367) from Dan Abramov (co-author of Redux).\n\nAll services use as a singleton object. There is no dependency injection needed because there is no service inheritance.\n\n### Key code snippets:\n\n#### Services\n\nFound in `/src/services`. Here you will find all of the basic interaction with the MongoDB Realm service.\n\nConnect MongoDB Realm - `stitch.service.js`:\n\n```js\n  get client() {\n    return this._localStitchClient;//For use the stitch client from another services\n  }\n\n  get database() {\n    if (!this._database) {\n      throw new Error(\"You are not logged in! Please, login first.\");\n    }\n    return this._database;\n  }\n\n  constructor() {\n    this._localStitchClient = Stitch.initializeDefaultAppClient(config.realmAppId);\n\n    // The database object will be available only after authentication\n    this._database = null;\n  }\n\n  // This method should be called from Login form with the Realm user credentials:\n  authenticateStitch(login, pass) {\n    return this._localStitchClient.auth\n      .loginWithCredential(new UserPasswordCredential(login, pass))\n      .then((user) =\u003e {\n        this.reinitializeClient();\n        return user;\n      });\n  }\n\n  //After stitch authentication, you can connect to the database\n  reinitializeClient() {\n    this._database = this._localStitchClient\n      .getServiceClient(RemoteMongoClient.factory, config.realmServiceName)\n      .db(config.database);\n  }\n```\n\nThere are also examples of calling Realm functions:\n\n```js\ngetVesselsWithFacet(limit, offset, search, filter) {\n    return this._localStitchClient.callFunction(\"searchFacetByVessels\", [limit, offset, search, filter]);\n  }\n```\n\n`auth.service.js` uses `EventEmitter` to fire an `authorized` event when authentication is complete:\n\n```js\nthis.emit(\"authorized\", user);\n```\n\nOther components subscribe to that event, for example the user profile component uses it as a trigger to display user information.\n\n\n#### Authentication\n\nAuthentication is invoked from `/src/root/root.component.js` through the `renderRoutes` method (`/src/helpers/map-routing.js`).\n\nThis method checks if the user is already authenticated and redirects the user to the login page if not:\n\n```js\nconst auth = authService.isStitchAuthenticated;\nif (route.auth){\n  if (!auth){\n    return \u003cRedirect to=\"/login\" /\u003e;\n  } else {\n    if (!authService.isAuthenticated){\n      return authService.reauthenticateUser().then(()=\u003e{\n        return \u003cRedirect to={route.path} /\u003e\n      });\n    }\n  }\n}\n\nif (route.redirectTo) return \u003cRedirect to={route.redirectTo} /\u003e;\n\nif (route.routes){\n  return \u003croute.component isLoggedIn={auth} {...props} routes={route.routes}/\u003e;\n} else {\n  return \u003croute.component isLoggedIn={auth} {...props} /\u003e;\n}\n};\n```\n\n#### MongoDB Charts\n\n`src/charts/chart-box.component.js` is a React-ready component to embed MongoDB Charts:\n\n```js\nexport default function ChartBox({ options, className })\n```\n\nExample chart options:\n\n```js\nconst chartOptions = {\n  width: \"100%\",\n  height: \"100%\",\n  refreshInterval: 1300, // in seconds.\n  useAuthenticatedAccess: true,\n  chartId: \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\n  filter: {exampleField: \"someValue\"}\n};\n```\n\n#### Pages\n\nThe code for each page is in `/src`.\n\nCommon components are in `/src/partials`.\n\n# Testing\n\n- Quick examples of Jest and React-Testing-Library tests in `src/test-examples/`\n- Read TESTS.md for detailed how-tos, setup, and test structure\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwildaid%2Fo-fish-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwildaid%2Fo-fish-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwildaid%2Fo-fish-web/lists"}