diff --git a/README.md b/README.md
index dd706ac..807bc77 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,19 @@
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+## Hi!
+Thank you for taking time to look at this work sample. This app is my personal site with the work sample added as a page at /truss.
+
## Getting Started
+First, clone the repo and navigate to the root of the project.
+
+Then, install the project dependencies:
+
+```bash
+npm install
+# or
+yarn
+```
-First, run the development server:
+Next, run the development server:
```bash
npm run dev
@@ -10,15 +21,23 @@ npm run dev
yarn dev
```
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+Checkout the branch that this feature is being developed on:
+```bash
+git checkout feature/truss
+```
+
+
+Finally, navigate to [http://localhost:3000/truss](http://localhost:3000/truss) to see the work sample. There is a navigation link in the header.
-You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
-[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+## Files to look at
+The files to be concerned with are `pages/truss.js` (displaying the table of planet data) and `hooks/useFetch.js` (abstracting the fetch into a custom hook to help with loading and error states).
-The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+(Please note the other pages in the app will not work without the api key environment variables. See briandridge.com if you are curious).
-## Learn More
+## Next.js resources
+
+The app is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
To learn more about Next.js, take a look at the following resources:
@@ -26,14 +45,3 @@ To learn more about Next.js, take a look at the following resources:
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
-
-## Weird stuff to know
-
-In Husky v5 git pre-commit hooks do not get created on install. Downgraded specifically to version 4.2.3 to make them work.
-See this issue: https://github.com/typicode/husky/issues/326#issuecomment-769309475
diff --git a/career-goals.md b/career-goals.md
deleted file mode 100644
index dc49ff3..0000000
--- a/career-goals.md
+++ /dev/null
@@ -1,27 +0,0 @@
-- How do you approach PM
- - Agile
- - Team makeup (cross-functional ?) roles?
-
-- Tell me about you develop talent
- - foster learning, give time resources for education
- - career ladder
- - leveling
- - performance - reviews?
-
-- 5 year vision and focus for company and eng team
-
-- Is devops a part of the cultrue?
- - CI/CD process
-
--
-
-
-- At this point, I'm interested in gaining breadth of knowledge - have FE down, want to start to learn more skills, eventually towards a Staff Engineer tech leadership role.ch$$
-
-- I want to be able to impact my teeammates quality of life by making building tools that take away toil and make their jobs joyful and interesting.
-
-- mission driven product organization.
-
-- product org consultancy can be hectic, no follow through, no planning, no communicty (silod teams)
-
-- want to make an impact and foster community and development in an engineering group
\ No newline at end of file
diff --git a/components/Header.jsx b/components/Header.jsx
index 7531a75..71028d1 100644
--- a/components/Header.jsx
+++ b/components/Header.jsx
@@ -27,9 +27,9 @@ const Header = () => {
Resume
-
+
- Blog
+ Truss Work Sample
fetch(url).then(res => res.json())
+
+ // Recursively get planet pages until data.next is null and all the pages are fetched, collect pages into a single array
+ const getAllPlanetPages = async (url, planetCollection = []) => {
+ const { results, next } = await getPlanetPage(url)
+ planetCollection = [...planetCollection, ...results]
+ if (next !== null) {
+ return getAllPlanetPages(next, planetCollection)
+ }
+ return planetCollection
+ }
+
+ // all planet data
+ const rawPlanets = await getAllPlanetPages('https://swapi.dev/api/planets/')
+
+ // alphabetically sort the collection of all planet data
+ const sortedPlanets = rawPlanets.sort((first, second) => {
+ const firstPlanet = first.name.toUpperCase()
+ const secondPlanet = second.name.toUpperCase()
+ return firstPlanet < secondPlanet ? -1 : firstPlanet > secondPlanet ? 1 : 0
+ })
+ return sortedPlanets
+}
+
+// custom hook to fetch data and provide loading, data, and error
+export const useFetch = url => {
+ const [loading, setLoading] = useState(false)
+ const [data, setData] = useState([])
+ const [error, setError] = useState(null)
+
+ useEffect(() => {
+ let isStale = false
+ setLoading(true)
+
+ fetch(url)
+ .then(res => res.json())
+ .then(data => {
+ if (!isStale) {
+ setData(data)
+ setError(null)
+ setLoading(false)
+ }
+ })
+ .catch(error => {
+ console.warn(error.message)
+ setError(error)
+ setLoading(false)
+ })
+
+ return () => {
+ isStale = true
+ }
+ }, [url])
+
+ return { loading, data, error }
+}
diff --git a/pages/truss.js b/pages/truss.js
new file mode 100644
index 0000000..5283142
--- /dev/null
+++ b/pages/truss.js
@@ -0,0 +1,137 @@
+/** @jsxRuntime classic /
+/* @jsx jsx */
+import { jsx, Flex, Spinner } from 'theme-ui'
+import Layout from '@components/Layout'
+import { useFetch } from '../hooks/useFetch'
+
+// take an integer and format with a space at every group of 3 (thousand)
+const formatNumber = number =>
+ number?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ') // https://stackoverflow.com/questions/16637051/adding-space-between-numbers
+
+// display a "?" in table if values are unknown
+const formatUnknown = value => (value === 'unknown' ? '?' : value)
+
+// calculate the surface area of a planet that is covered by water
+const calculateSurfaceAreaCoveredByWater = (
+ planetDiameter,
+ percentageCoveredByWater
+) => {
+ const planetRadius = planetDiameter / 2
+ const totalSurfaceArea = 4 * Math.PI * Math.pow(planetRadius, 2) // use this calc to confirm: https://www.calculatorsoup.com/calculators/geometry-solids/sphere.php
+ const areaCoveredByWater = totalSurfaceArea * (percentageCoveredByWater / 100)
+ return areaCoveredByWater ? formatNumber(Math.round(areaCoveredByWater)) : '?'
+}
+
+// display planet data in a table (with loading and error states)
+const Planets = () => {
+ const { loading, data, error } = useFetch('https://swapi.dev/api/planets/')
+
+ // alphabetically sort the planet data
+ const sortedPlanets = data.results?.sort((first, second) => {
+ const firstPlanet = first.name.toUpperCase()
+ const secondPlanet = second.name.toUpperCase()
+ return firstPlanet < secondPlanet ? -1 : firstPlanet > secondPlanet ? 1 : 0
+ })
+
+ // if data is loading show a spinner
+ if (loading) {
+ return
Planet | +Climate | +Residents | +Terrain | +Population | +Surface area water | +
---|---|---|---|---|---|
+ + {formatUnknown(planet.name)} + + | +{formatUnknown(planet.climate)} | +{planet.residents?.length} | +{formatUnknown(planet.terrain)} | +{formatUnknown(formatNumber(planet.population))} | ++ {calculateSurfaceAreaCoveredByWater( + planet.diameter, + planet.surface_water + )} + | +