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
32 changes: 32 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI for Node.js React Sample App
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- uses: actions/setup-python@v5
with:
python-version: 3.9

- name: Install client
run: yarn --cwd client install

- name: Lint client source
run: yarn --cwd client lint

- name: Install server (Python) and lint
run: |
cd server
python -m venv bb2_venv
. ./bb2_venv/bin/activate
pip install pipenv flake8
pip install cms-bluebutton-sdk
pipenv lock
pipenv install --system --deploy --ignore-pipfile
flake8 --exclude bb2_venv --max-line-length 130
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,28 @@ Running the Back-end & Front-end
---------------

Once Docker and Python are Installed then do the following:


```
cp server/sample-bluebutton-config.json server/.bluebutton-config.json
```

Make sure to replace the client_id and client_secret variables within the config file with
the ones you were provided, for your application, when you created your Blue Button Sandbox account,
the supported environments are SANDBOX or PRODUCTION.

```
docker-compose up -d
```

This single command will create the docker container with all the necessary packages, configuration, and code to
run both the front and back ends of this sample application.

To run the front-end (client component listening on port 3000) in preview mode, set environment variable BB2_APP_LAUNCH=preview when launch docker-compose:

```
BB2_APP_LAUNCH=preview docker-compose up -d
```

To see the application in action open your browser and enter the following URL:

http://localhost:3000
Expand Down
5 changes: 5 additions & 0 deletions client/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": [
"react-app"
]
}
10 changes: 8 additions & 2 deletions client/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
FROM node:20-slim
FROM node:22

ARG BB2-APP_LAUNCH

ENV BB2_APP_LAUNCH=${BB2_APP_LAUNCH:-"start"}

LABEL version="1.1"
LABEL description="Demo of a Medicare claims data sample app"
Expand All @@ -13,7 +17,9 @@ RUN apt-get install python3 -y
RUN apt-get install python3-pip -y

RUN yarn install
# comment build out if not going to use preview to save build time
RUN yarn build

EXPOSE 3000

CMD ["yarn","start"]
CMD ["sh", "-c", "yarn $BB2_APP_LAUNCH"]
28 changes: 12 additions & 16 deletions client/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Getting Started with Create React App
# Getting Started with Vite

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
This project was created with build tool [Vite](https://v2.vitejs.dev/).
Vite (French word for "quick", pronounced /vit/, like "veet") is a build tool that aims to provide a faster and leaner development experience for modern web projects.

## Available Scripts

Expand All @@ -14,11 +15,6 @@ Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.

### `yarn test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `yarn build`

Builds the app for production to the `build` folder.\
Expand All @@ -27,20 +23,20 @@ It correctly bundles React in production mode and optimizes the build for the be
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `yarn preview`

### `yarn eject`
Locally preview the production build. Do not use this as a production server as it's not designed for it.

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
## Learn More

If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
You can learn more in the [Vite documentation: Getting Started](https://v2.vitejs.dev/guide/).

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
To learn React, check out the [React documentation](https://reactjs.org/).

You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
### `yarn test`

## Learn More
Run vitest based test (need spinning up the app to pass the tests)

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
### `yarn coverage`

To learn React, check out the [React documentation](https://reactjs.org/).
Run vitest based test with coverage (need spinning up the app to pass the tests)
17 changes: 17 additions & 0 deletions client/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { fixupConfigRules } from "@eslint/compat";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});

export default [{
ignores: [],
}, ...fixupConfigRules(compat.extends("react-app"))];
25 changes: 25 additions & 0 deletions client/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
20 changes: 20 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Blue Button 2.0 Sample App"
/>
<link rel="manifest" href="/manifest.json" />
<title>Medicare claims data sample app</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
38 changes: 24 additions & 14 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@
"private": true,
"proxy": "http://localhost:3001",
"dependencies": {
"@cmsgov/design-system": "^2.7.3",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@cmsgov/design-system": "^10.1.0",
"@types/node": "^22.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react-swc": "^3.7.2",
"axios": "^1.7.4",
"http-proxy-middleware": "^1.3.1",
"micromatch": "4.0.8",
"process": "^0.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.2",
"react-scripts": "5.0.1",
"sass": "1.72.0",
"typescript": "^4.8.4",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.3",
"web-vitals": "^3.0.3"
},
"scripts": {
"start": "REACT_APP_CTX=docker react-scripts start",
"start-native": "REACT_APP_CTX=native react-scripts start",
"lint": "eslint --ext .ts --ext .js --ext .tsx .",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"start": "vite dev --host",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint --max-warnings=100 src",
"test": "TEST_APP_API_URL=http://localhost:3000 vitest",
"coverage": "TEST_APP_API_URL=http://localhost:3000 vitest run --coverage"
},
"eslintConfig": {
"extends": [
Expand All @@ -46,15 +48,23 @@
]
},
"devDependencies": {
"@eslint/compat": "^1.2.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^29.1.2",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint-config-react-app": "^7.0.0",
"eslint-plugin-react": "^7.28.0"
"@vitest/coverage-v8": "2.1.6",
"eslint": "^9.16.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-react": "^7.28.0",
"jsdom": "^25.0.1",
"react-error-overlay": "6.0.9",
"vite": "^6.0.0",
"vite-plugin-eslint": "^1.8.1",
"vitest": "^2.1.6"
},
"resolutions": {
"@types/react": "^17.0.2"
Expand Down
42 changes: 0 additions & 42 deletions client/public/index.html

This file was deleted.

6 changes: 4 additions & 2 deletions client/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import { test } from 'vitest';
import { render, screen } from '@testing-library/react';

import App from './App';

test('renders learn react link', () => {
test('renders sample app landing page', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
const linkElement = screen.getByText(/patient information/i);
expect(linkElement).toBeInTheDocument();
});
6 changes: 3 additions & 3 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Header from './components/header';
import Patient from './components/patient';
import Header from '../src/components/header';
import Patient from '../src/components/patient';
import PatientData from './components/patientData';
import Records from './components/records';
import { BrowserRouter as Router} from "react-router-dom";
Expand All @@ -9,8 +9,8 @@ import { TabPanel, Tabs } from '@cmsgov/design-system';
function App() {
return (
<div className="ds-l-container ds-u-margin-bottom--7 ds-u-padding-bottom--7">
<Header />
<Router>
<Header />
<Tabs tablistClassName="ds-u-margin-top--3">
<TabPanel id="patient" tab="Patient info">
<h2>Patient information</h2>
Expand Down
9 changes: 3 additions & 6 deletions client/src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { Badge } from '@cmsgov/design-system';
import { Link as RouterLink } from 'react-router-dom';
import React from 'react'

export default function Header() {
return (
return (
<header className="ds-u-padding--3 ds-u-sm-padding--6 ds-u-display--block ds-u-fill--primary-darkest">
<h1 className="ds-u-margin--0 ds-u-color--white ds-u-font-size--display ds-u-text-align--center">
<RouterLink to="/" style={{ textDecoration: 'none', color: 'inherit' }}>
<h1 className="ds-u-margin--0 ds-u-color--white ds-u-font-size--5xl ds-u-text-align--center">
Blue Button 2.0 Sample App
</RouterLink>
</h1>
<div className="ds-u-text-align--center">
<Badge variation="info" size="big">
Medicare Prescription Drug Claims Data
</Badge>
</div>
</header>
);
);
}
Loading
Loading