Skip to content

Commit a6caa83

Browse files
committed
replace CRA with vite and refactor as needed.
1 parent 63803a8 commit a6caa83

23 files changed

+3705
-7173
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,28 @@ Running the Back-end & Front-end
2424
---------------
2525

2626
Once Docker and Python are Installed then do the following:
27-
27+
28+
```
2829
cp server/sample-bluebutton-config.json server/.bluebutton-config.json
30+
```
2931

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

36+
```
3437
docker-compose up -d
38+
```
3539

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

43+
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:
44+
45+
```
46+
BB2_APP_LAUNCH=preview docker-compose up -d
47+
```
48+
3949
To see the application in action open your browser and enter the following URL:
4050

4151
http://localhost:3000

client/.eslintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": [
3+
"react-app"
4+
]
5+
}

client/Dockerfile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
FROM node:20-slim
1+
FROM node:22
2+
3+
ARG BB2-APP_LAUNCH
4+
5+
ENV BB2_APP_LAUNCH=${BB2_APP_LAUNCH:-"start"}
26

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

1519
RUN yarn install
20+
# comment build out if not going to use preview to save build time
21+
RUN yarn build
1622

1723
EXPOSE 3000
1824

19-
CMD ["yarn","start"]
25+
CMD ["sh", "-c", "yarn $BB2_APP_LAUNCH"]

client/README.md

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# Getting Started with Create React App
1+
# Getting Started with Vite
22

3-
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
3+
This project was created with build tool [Vite](https://v2.vitejs.dev/).
4+
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.
45

56
## Available Scripts
67

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

17-
### `yarn test`
18-
19-
Launches the test runner in the interactive watch mode.\
20-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21-
2218
### `yarn build`
2319

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

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

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

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

36-
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.
32+
You can learn more in the [Vite documentation: Getting Started](https://v2.vitejs.dev/guide/).
3733

38-
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.
34+
To learn React, check out the [React documentation](https://reactjs.org/).
3935

40-
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.
36+
### `yarn test`
4137

42-
## Learn More
38+
Run vitest based test (need spinning up the app to pass the tests)
4339

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

46-
To learn React, check out the [React documentation](https://reactjs.org/).
42+
Run vitest based test with coverage (need spinning up the app to pass the tests)

client/eslint.config.mjs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { fixupConfigRules } from "@eslint/compat";
2+
import path from "node:path";
3+
import { fileURLToPath } from "node:url";
4+
import js from "@eslint/js";
5+
import { FlatCompat } from "@eslint/eslintrc";
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = path.dirname(__filename);
9+
const compat = new FlatCompat({
10+
baseDirectory: __dirname,
11+
recommendedConfig: js.configs.recommended,
12+
allConfig: js.configs.all
13+
});
14+
15+
export default [{
16+
ignores: [],
17+
}, ...fixupConfigRules(compat.extends("react-app"))];

client/eslintrc.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:react/recommended",
9+
"plugin:@typescript-eslint/recommended"
10+
],
11+
"parser": "@typescript-eslint/parser",
12+
"parserOptions": {
13+
"ecmaFeatures": {
14+
"jsx": true
15+
},
16+
"ecmaVersion": 12
17+
},
18+
"plugins": [
19+
"react",
20+
"@typescript-eslint"
21+
],
22+
"rules": {
23+
"@typescript-eslint/no-explicit-any": "off"
24+
}
25+
}

client/index.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
<meta name="theme-color" content="#000000" />
8+
<meta
9+
name="description"
10+
content="Blue Button 2.0 Sample App"
11+
/>
12+
<link rel="manifest" href="/manifest.json" />
13+
<title>Medicare claims data sample app</title>
14+
</head>
15+
<body>
16+
<noscript>You need to enable JavaScript to run this app.</noscript>
17+
<div id="root"></div>
18+
<script type="module" src="/src/index.tsx"></script>
19+
</body>
20+
</html>

client/package.json

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,30 @@
44
"private": true,
55
"proxy": "http://localhost:3001",
66
"dependencies": {
7-
"@cmsgov/design-system": "^2.7.3",
8-
"@types/node": "^12.0.0",
9-
"@types/react": "^17.0.0",
10-
"@types/react-dom": "^17.0.0",
7+
"@cmsgov/design-system": "^10.1.0",
8+
"@types/node": "^22.0.0",
9+
"@types/react": "^18.2.0",
10+
"@types/react-dom": "^18.2.0",
11+
"@vitejs/plugin-react-swc": "^3.7.2",
1112
"axios": "^1.7.4",
12-
"http-proxy-middleware": "^1.3.1",
1313
"micromatch": "4.0.8",
14+
"process": "^0.11.10",
1415
"react": "^18.2.0",
1516
"react-dom": "^18.2.0",
1617
"react-router-dom": "^6.4.2",
17-
"react-scripts": "5.0.1",
1818
"sass": "1.72.0",
1919
"typescript": "^4.8.4",
20+
"vite-plugin-svgr": "^4.3.0",
21+
"vite-tsconfig-paths": "^5.1.3",
2022
"web-vitals": "^3.0.3"
2123
},
2224
"scripts": {
23-
"start": "REACT_APP_CTX=docker react-scripts start",
24-
"start-native": "REACT_APP_CTX=native react-scripts start",
25-
"lint": "eslint --ext .ts --ext .js --ext .tsx .",
26-
"build": "react-scripts build",
27-
"test": "react-scripts test",
28-
"eject": "react-scripts eject"
25+
"start": "vite dev --host",
26+
"build": "vite build",
27+
"preview": "vite preview",
28+
"lint": "eslint --max-warnings=100 src",
29+
"test": "TEST_APP_API_URL=http://localhost:3000 vitest",
30+
"coverage": "TEST_APP_API_URL=http://localhost:3000 vitest run --coverage"
2931
},
3032
"eslintConfig": {
3133
"extends": [
@@ -46,15 +48,23 @@
4648
]
4749
},
4850
"devDependencies": {
51+
"@eslint/compat": "^1.2.3",
4952
"@testing-library/jest-dom": "^5.16.5",
5053
"@testing-library/react": "^13.4.0",
5154
"@testing-library/user-event": "^13.5.0",
5255
"@types/jest": "^29.1.2",
5356
"@types/react-router-dom": "^5.3.3",
5457
"@typescript-eslint/eslint-plugin": "^5.12.0",
5558
"@typescript-eslint/parser": "^5.12.0",
56-
"eslint-config-react-app": "^7.0.0",
57-
"eslint-plugin-react": "^7.28.0"
59+
"@vitest/coverage-v8": "2.1.6",
60+
"eslint": "^9.16.0",
61+
"eslint-config-react-app": "^7.0.1",
62+
"eslint-plugin-react": "^7.28.0",
63+
"jsdom": "^25.0.1",
64+
"react-error-overlay": "6.0.9",
65+
"vite": "^6.0.0",
66+
"vite-plugin-eslint": "^1.8.1",
67+
"vitest": "^2.1.6"
5868
},
5969
"resolutions": {
6070
"@types/react": "^17.0.2"

client/public/index.html

Lines changed: 0 additions & 42 deletions
This file was deleted.

client/src/App.test.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React from 'react';
2+
import { test } from 'vitest';
23
import { render, screen } from '@testing-library/react';
4+
35
import App from './App';
46

5-
test('renders learn react link', () => {
7+
test('renders sample app landing page', () => {
68
render(<App />);
7-
const linkElement = screen.getByText(/learn react/i);
9+
const linkElement = screen.getByText(/patient information/i);
810
expect(linkElement).toBeInTheDocument();
911
});

client/src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
2-
import Header from './components/header';
3-
import Patient from './components/patient';
2+
import Header from '../src/components/header';
3+
import Patient from '../src/components/patient';
44
import PatientData from './components/patientData';
55
import Records from './components/records';
66
import { BrowserRouter as Router} from "react-router-dom";
@@ -9,8 +9,8 @@ import { TabPanel, Tabs } from '@cmsgov/design-system';
99
function App() {
1010
return (
1111
<div className="ds-l-container ds-u-margin-bottom--7 ds-u-padding-bottom--7">
12+
<Header />
1213
<Router>
13-
<Header />
1414
<Tabs tablistClassName="ds-u-margin-top--3">
1515
<TabPanel id="patient" tab="Patient info">
1616
<h2>Patient information</h2>

client/src/components/header.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import { Badge } from '@cmsgov/design-system';
2-
import { Link as RouterLink } from 'react-router-dom';
32
import React from 'react'
43

54
export default function Header() {
6-
return (
5+
return (
76
<header className="ds-u-padding--3 ds-u-sm-padding--6 ds-u-display--block ds-u-fill--primary-darkest">
8-
<h1 className="ds-u-margin--0 ds-u-color--white ds-u-font-size--display ds-u-text-align--center">
9-
<RouterLink to="/" style={{ textDecoration: 'none', color: 'inherit' }}>
7+
<h1 className="ds-u-margin--0 ds-u-color--white ds-u-font-size--5xl ds-u-text-align--center">
108
Blue Button 2.0 Sample App
11-
</RouterLink>
129
</h1>
1310
<div className="ds-u-text-align--center">
1411
<Badge variation="info" size="big">
1512
Medicare Prescription Drug Claims Data
1613
</Badge>
1714
</div>
1815
</header>
19-
);
16+
);
2017
}

client/src/components/patientData.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
import { Button } from '@cmsgov/design-system';
22
import axios from 'axios';
33
import chart from '../images/who-charted.png'
4-
import { SettingsType } from '../types/settings';
4+
//import { SettingsType } from '../types/settings';
55
import React, { useState } from 'react';
6+
import * as process from 'process';
67

78
export default function PatientData() {
89
const [header] = useState('Add your Medicare Prescription Drug data');
9-
const [settingsState] = useState<SettingsType>({
10-
pkce: true,
11-
version: 'v2',
12-
env: 'sandbox'
13-
});
10+
// comment out below because the end point /api/authorize/authurl of
11+
// the server component (on port 3001), does not take parameter such as pkce, version, env
12+
// they are generated by the server component.
13+
//
14+
// const [settingsState] = useState<SettingsType>({
15+
// pkce: true,
16+
// version: 'v2',
17+
// env: 'sandbox'
18+
// });
1419
async function goAuthorize() {
15-
const authUrlResponse = await axios.get(`/api/authorize/authurl`, { params: settingsState });
16-
window.location.href = authUrlResponse.data || '/';
20+
// comment out '{ params: settingsState }' since /api/authorize/authurl does not take params
21+
const test_url = process.env.TEST_APP_API_URL ? process.env.TEST_APP_API_URL : ''
22+
const authUrlResponseData = await axios.get(`${test_url}/api/authorize/authurl`/*, { params: settingsState } */)
23+
.then(response => {
24+
return response.data;
25+
})
26+
.then(data => {
27+
window.location.href = data;
28+
})
29+
.catch(error => {
30+
window.location.href = "/";
31+
});
32+
console.log(authUrlResponseData);
1733
}
1834

1935
/* DEVELOPER NOTES:
@@ -34,7 +50,7 @@ export default function PatientData() {
3450
<div>
3551
<h4>{ header }</h4>
3652
</div>
37-
<Button id="auth_btn" variation="primary" onClick={goAuthorize}>Authorize</Button>
53+
<Button id="auth_btn" variation="solid" onClick={goAuthorize}>Authorize</Button>
3854
</div>
3955
</div>
4056
);

0 commit comments

Comments
 (0)