From 6053a042683c6942e8b5656daa81932512f440fc Mon Sep 17 00:00:00 2001 From: Rafael Date: Sat, 7 Nov 2020 20:32:35 -0300 Subject: [PATCH 01/12] wip --- .babelrc | 4 - .eslintrc.json | 28 - .gitignore | 4 + README.md | 30 - components/Error.js | 25 - components/Footer.js | 40 - components/Grid.js | 108 - components/Header.js | 40 - components/Info.js | 71 - components/Layout.js | 38 - components/Layout.tsx | 41 + components/List.tsx | 19 + components/ListDetail.tsx | 16 + components/ListItem.tsx | 18 + components/Loader.js | 25 - components/Map.js | 72 - components/MutedText.js | 11 - components/Navbar.js | 32 - components/Page.js | 38 - components/Run.js | 96 - components/Runs.js | 26 - components/Switch.js | 76 - components/Text.js | 12 - components/Wrapper.js | 44 - hooks/useIsBottomOfThePage.js | 20 - images/exclamation-triangle.svg | 6 - interfaces/index.ts | 10 + models/run.js | 34 - next-env.d.ts | 2 + next.config.js | 13 - package.json | 43 +- pages/_app.js | 24 - pages/_document.js | 45 - pages/api/average-distance.js | 21 - pages/api/average-pace.js | 25 - pages/api/runs.js | 22 - pages/api/runs.ts | 15 + pages/api/sync.js | 32 - pages/api/total-distance.js | 21 - pages/api/total-runs.js | 14 - pages/api/webhook.js | 34 - pages/index.js | 18 - pages/index.tsx | 15 + public/TTFirsNeue-DemiBold.eot | Bin 122908 -> 0 bytes public/TTFirsNeue-DemiBold.ttf | Bin 122684 -> 0 bytes public/TTFirsNeue-DemiBold.woff | Bin 52448 -> 0 bytes public/TTFirsNeue-DemiBold.woff2 | Bin 36424 -> 0 bytes styles/index.css | 28 - tsconfig.json | 23 + utils/addRun.js | 49 - utils/calculatePace.js | 5 - utils/constants.js | 3 - utils/formatDate.js | 9 - utils/formatPace.js | 7 - utils/formatTime.js | 14 - utils/getDay.js | 7 - utils/mapbox/getLocation.js | 25 - utils/meteostat/getHourlyData.js | 26 - utils/meteostat/getWeather.js | 19 - utils/meteostat/weather-condition-codes.json | 29 - utils/middlewares/connectDb.js | 17 - utils/mongodb.ts | 33 + utils/sample-data.ts | 9 + utils/strava/getActivityById.js | 18 - utils/strava/getLoggedInAthleteActivities.js | 31 - utils/strava/getRefreshedToken.js | 29 - utils/theme.js | 41 - yarn.lock | 6452 +++--------------- 68 files changed, 1232 insertions(+), 6970 deletions(-) delete mode 100644 .babelrc delete mode 100644 .eslintrc.json delete mode 100644 README.md delete mode 100644 components/Error.js delete mode 100644 components/Footer.js delete mode 100644 components/Grid.js delete mode 100644 components/Header.js delete mode 100644 components/Info.js delete mode 100644 components/Layout.js create mode 100644 components/Layout.tsx create mode 100644 components/List.tsx create mode 100644 components/ListDetail.tsx create mode 100644 components/ListItem.tsx delete mode 100644 components/Loader.js delete mode 100644 components/Map.js delete mode 100644 components/MutedText.js delete mode 100644 components/Navbar.js delete mode 100644 components/Page.js delete mode 100644 components/Run.js delete mode 100644 components/Runs.js delete mode 100644 components/Switch.js delete mode 100644 components/Text.js delete mode 100644 components/Wrapper.js delete mode 100644 hooks/useIsBottomOfThePage.js delete mode 100644 images/exclamation-triangle.svg create mode 100644 interfaces/index.ts delete mode 100644 models/run.js create mode 100644 next-env.d.ts delete mode 100644 next.config.js delete mode 100644 pages/_app.js delete mode 100644 pages/_document.js delete mode 100644 pages/api/average-distance.js delete mode 100644 pages/api/average-pace.js delete mode 100644 pages/api/runs.js create mode 100644 pages/api/runs.ts delete mode 100644 pages/api/sync.js delete mode 100644 pages/api/total-distance.js delete mode 100644 pages/api/total-runs.js delete mode 100644 pages/api/webhook.js delete mode 100644 pages/index.js create mode 100644 pages/index.tsx delete mode 100644 public/TTFirsNeue-DemiBold.eot delete mode 100644 public/TTFirsNeue-DemiBold.ttf delete mode 100644 public/TTFirsNeue-DemiBold.woff delete mode 100644 public/TTFirsNeue-DemiBold.woff2 delete mode 100644 styles/index.css create mode 100644 tsconfig.json delete mode 100644 utils/addRun.js delete mode 100644 utils/calculatePace.js delete mode 100644 utils/constants.js delete mode 100644 utils/formatDate.js delete mode 100644 utils/formatPace.js delete mode 100644 utils/formatTime.js delete mode 100644 utils/getDay.js delete mode 100644 utils/mapbox/getLocation.js delete mode 100644 utils/meteostat/getHourlyData.js delete mode 100644 utils/meteostat/getWeather.js delete mode 100644 utils/meteostat/weather-condition-codes.json delete mode 100644 utils/middlewares/connectDb.js create mode 100644 utils/mongodb.ts create mode 100644 utils/sample-data.ts delete mode 100644 utils/strava/getActivityById.js delete mode 100644 utils/strava/getLoggedInAthleteActivities.js delete mode 100644 utils/strava/getRefreshedToken.js delete mode 100644 utils/theme.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 854cb73..0000000 --- a/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["next/babel"], - "plugins": [["styled-components", { "ssr": true }]] -} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index ff87843..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "env": { - "browser": true, - "es2020": true, - "node": true - }, - "extends": ["eslint:recommended", "plugin:react/recommended"], - "globals": { - "React": "writable" - }, - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 11, - "sourceType": "module" - }, - "plugins": ["react"], - "rules": { - "react/react-in-jsx-scope": "off", - "react/prop-types": "off" - }, - "settings": { - "react": { - "version": "detect" - } - } -} diff --git a/.gitignore b/.gitignore index 20fccdd..1437c53 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ # misc .DS_Store +*.pem # debug npm-debug.log* @@ -28,3 +29,6 @@ yarn-error.log* .env.development.local .env.test.local .env.production.local + +# vercel +.vercel diff --git a/README.md b/README.md deleted file mode 100644 index 4b5c883..0000000 --- a/README.md +++ /dev/null @@ -1,30 +0,0 @@ -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). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [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. diff --git a/components/Error.js b/components/Error.js deleted file mode 100644 index 2fe8fd0..0000000 --- a/components/Error.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import styled from 'styled-components' - -import ExclamationTriangle from '../images/exclamation-triangle.svg' - -const StyledError = styled.div` - align-items: center; - color: currentColor; - display: flex; - height: 100%; - justify-content: center; - width: 100%; - - svg { - width: 100px; - } -` - -const Error = () => ( - - - -) - -export default Error diff --git a/components/Footer.js b/components/Footer.js deleted file mode 100644 index a4bd593..0000000 --- a/components/Footer.js +++ /dev/null @@ -1,40 +0,0 @@ -import styled from 'styled-components' - -import Text from './Text' - -const StyledFooter = styled.footer` - margin-top: 32px; - padding: 16px; - text-align: center; - - a { - color: currentColor; - text-decoration: none; - } -` - -const Footer = () => ( - - {new Date().getFullYear()} - {' | '} - - rfoel - - {' | '} - - source code - - -) - -export default Footer diff --git a/components/Grid.js b/components/Grid.js deleted file mode 100644 index 96f6077..0000000 --- a/components/Grid.js +++ /dev/null @@ -1,108 +0,0 @@ -import styled, { css } from 'styled-components' -import { up, down } from 'styled-breakpoints' - -export const Grid = styled.div( - ({ - theme: { - grid: { breakpoints, width }, - }, - }) => css` - margin-right: auto; - margin-left: auto; - width: 100%; - - ${breakpoints.map( - breakpoint => css` - ${up(breakpoint)} { - max-width: ${width[breakpoint]}; - } - `, - )} - `, -) - -export const Row = styled.div( - ({ - align, - justify, - theme: { - grid: { breakpoints, gutter }, - }, - }) => css` - display: flex; - flex: 1 1 auto; - flex-wrap: wrap; - - ${breakpoints.map( - breakpoint => css` - ${up(breakpoint)} { - margin-left: -${gutter[breakpoint] / 2}px; - margin-right: -${gutter[breakpoint] / 2}px; - } - `, - )} - - ${ - align && - css` - align-items: ${align}; - ` - } - - ${ - justify && - css` - justify-content: ${justify}; - ` - } - `, -) - -export const Column = styled.div( - ({ - align, - justify, - theme: { - grid: { breakpoints, columns, gutter }, - }, - ...props - }) => css` - display: flex; - flex: 1 0 auto; - flex-direction: column; - - ${breakpoints.map( - breakpoint => - props[breakpoint] && - css` - ${down(breakpoint)} { - flex: 1 1 ${(props[breakpoint] / columns[breakpoint]) * 100}%; - max-width: ${(props[breakpoint] / columns[breakpoint]) * 100}%; - } - `, - )} - - ${breakpoints.map( - breakpoint => css` - ${up(breakpoint)} { - padding-left: ${gutter[breakpoint] / 2}px; - padding-right: ${gutter[breakpoint] / 2}px; - } - `, - )} - - ${ - align && - css` - align-items: ${align}; - ` - } - - ${ - justify && - css` - justify-content: ${justify}; - ` - } - `, -) diff --git a/components/Header.js b/components/Header.js deleted file mode 100644 index 2f7a34a..0000000 --- a/components/Header.js +++ /dev/null @@ -1,40 +0,0 @@ -import useSWR from 'swr' -import styled, { css } from 'styled-components' -import ContentLoader from 'styled-content-loader' - -import MutedText from './MutedText' -import Text from './Text' - -const StyledHeader = styled(ContentLoader)( - () => css` - align-items: center; - display: flex; - flex-direction: column; - height: 156px; - justify-content: center; - - ${Text} { - font-size: 56px; - line-height: 56px; - margin-bottom: 8px; - } - - ${MutedText} { - font-size: 16px; - line-height: 16px; - } - `, -) - -const Header = () => { - const { data: totalDistance, error } = useSWR('/api/total-distance') - - return ( - - {(totalDistance / 1000).toFixed(2)} km - Total kilometers - - ) -} - -export default Header diff --git a/components/Info.js b/components/Info.js deleted file mode 100644 index d557838..0000000 --- a/components/Info.js +++ /dev/null @@ -1,71 +0,0 @@ -import useSWR from 'swr' -import styled from 'styled-components' -import ContentLoader from 'styled-content-loader' - -import formatPace from '../utils/formatPace' -import MutedText from './MutedText' -import Text from './Text' -import { Row, Column } from './Grid' -import { WORLD_RECORD } from '../utils/constants' - -const StyledInfo = styled.div` - width: 100%; - - ${Column}, ${Row} { - align-items: center; - justify-content: center; - } - - ${Column} { - height: 156px; - } - - ${Text} { - font-size: 40px; - margin-bottom: 8px; - } - - ${MutedText} { - font-size: 16px; - } -` - -const Info = () => { - const { data: totalRuns, error: totalRunsError } = useSWR('/api/total-runs') - const { data: averageDistance, error: averageDistanceError } = useSWR( - '/api/average-distance', - ) - const { data: averagePace, error: averagePaceError } = useSWR( - '/api/average-pace', - ) - - const error = totalRunsError || averageDistanceError || averagePaceError - const isLoading = Boolean( - !totalRuns || !averageDistance || !averagePace || error, - ) - - return ( - - - - {totalRuns || 999} - Total runs - - - {((totalRuns * 100) / WORLD_RECORD).toFixed(2)}% - WR progress - - - {(averageDistance / 1000).toFixed(2)} km - Average distance - - - {formatPace(averagePace)} - Average pace - - - - ) -} - -export default Info diff --git a/components/Layout.js b/components/Layout.js deleted file mode 100644 index 62410f4..0000000 --- a/components/Layout.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { node } from 'prop-types' -import styled, { css } from 'styled-components' - -import { Grid } from './Grid' - -const Container = styled.div( - ({ theme: { colors } }) => - css` - background-color: ${colors.base}; - color: ${colors.contrast}; - display: flex; - flex: 1 0 auto; - flex-direction: column; - transition-property: all; - transition-duration: 200ms; - transition-timing-function: ease; - width: 100%; - - > ${Grid} { - display: flex; - flex: 1 0 auto; - flex-direction: column; - } - `, -) - -const Layout = ({ children }) => ( - - {children} - -) - -Layout.propTypes = { - children: node.isRequired, -} - -export default Layout diff --git a/components/Layout.tsx b/components/Layout.tsx new file mode 100644 index 0000000..8f111e1 --- /dev/null +++ b/components/Layout.tsx @@ -0,0 +1,41 @@ +import React, { ReactNode } from 'react' +import Link from 'next/link' +import Head from 'next/head' + +type Props = { + children?: ReactNode + title?: string +} + +const Layout = ({ children, title = 'This is the default title' }: Props) => ( +
+ + {title} + + + +
+ +
+ {children} +
+
+ I'm here to stay (Footer) +
+
+) + +export default Layout diff --git a/components/List.tsx b/components/List.tsx new file mode 100644 index 0000000..5fe5ef2 --- /dev/null +++ b/components/List.tsx @@ -0,0 +1,19 @@ +import * as React from 'react' +import ListItem from './ListItem' +import { User } from '../interfaces' + +type Props = { + items: User[] +} + +const List = ({ items }: Props) => ( + +) + +export default List diff --git a/components/ListDetail.tsx b/components/ListDetail.tsx new file mode 100644 index 0000000..fa3f9c3 --- /dev/null +++ b/components/ListDetail.tsx @@ -0,0 +1,16 @@ +import * as React from 'react' + +import { User } from '../interfaces' + +type ListDetailProps = { + item: User +} + +const ListDetail = ({ item: user }: ListDetailProps) => ( +
+

Detail for {user.name}

+

ID: {user.id}

+
+) + +export default ListDetail diff --git a/components/ListItem.tsx b/components/ListItem.tsx new file mode 100644 index 0000000..b10b9c8 --- /dev/null +++ b/components/ListItem.tsx @@ -0,0 +1,18 @@ +import React from 'react' +import Link from 'next/link' + +import { User } from '../interfaces' + +type Props = { + data: User +} + +const ListItem = ({ data }: Props) => ( + + + {data.id}: {data.name} + + +) + +export default ListItem diff --git a/components/Loader.js b/components/Loader.js deleted file mode 100644 index 1dcd976..0000000 --- a/components/Loader.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import styled from 'styled-components' - -import Run from '../images/run.svg' - -const StyledLoader = styled.div` - align-items: center; - color: currentColor; - display: flex; - height: 100%; - justify-content: center; - width: 100%; - - svg { - width: 100px; - } -` - -const Loader = () => ( - - - -) - -export default Loader diff --git a/components/Map.js b/components/Map.js deleted file mode 100644 index 4ec477f..0000000 --- a/components/Map.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import polyline from '@mapbox/polyline' - -const Svg = styled.svg` - overflow: visible; - height: auto; -` - -const convertLatLngToPoint = ([lat, lng]) => { - return { - x: (lng + 180) * (256 / 360), - y: - 256 / 2 - - (256 * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 180 / 2))) / - (2 * Math.PI), - } -} - -const getPolylineProps = latLng => { - const points = [] - let minX = 256 - let minY = 256 - let maxX = 0 - let maxY = 0 - - for (var pp = 0; pp < latLng.length; ++pp) { - const currentLatLng = latLng[pp] - for (var p = 0; p < currentLatLng.length; ++p) { - const point = convertLatLngToPoint(currentLatLng) - minX = Math.min(minX, point.x) - minY = Math.min(minY, point.y) - maxX = Math.max(maxX, point.x) - maxY = Math.max(maxY, point.y) - points.push([point.x, point.y].join(',')) - } - } - - return { - points: points.join(' '), - x: minX, - y: minY, - width: maxX - minX, - height: maxY - minY, - } -} - -const Map = ({ summaryPolyline }) => { - const latLng = polyline.decode(summaryPolyline) - const { height, points, x, y, width } = getPolylineProps(latLng) - - return ( - - - - ) -} - -export default Map diff --git a/components/MutedText.js b/components/MutedText.js deleted file mode 100644 index 87875f0..0000000 --- a/components/MutedText.js +++ /dev/null @@ -1,11 +0,0 @@ -import styled, { css } from 'styled-components' - -import Text from './Text' - -const MutedText = styled(Text)( - ({ theme: { colors } }) => css` - color: ${colors.muted}; - `, -) - -export default MutedText diff --git a/components/Navbar.js b/components/Navbar.js deleted file mode 100644 index 8a07d45..0000000 --- a/components/Navbar.js +++ /dev/null @@ -1,32 +0,0 @@ -import { useRecoilState } from 'recoil' -import styled from 'styled-components' - -import Run from '../images/run.svg' -import Switch from './Switch' -import { darkModeAtom } from '../utils/theme' - -const StyledNavbar = styled.nav` - align-items: center; - color: currentColor; - display: flex; - justify-content: space-between; - padding: 16px; - width: 100%; - - svg { - width: 46px; - } -` - -const Navbar = () => { - const [darkMode, setDarkMode] = useRecoilState(darkModeAtom) - - return ( - - - setDarkMode(!darkMode)} /> - - ) -} - -export default Navbar diff --git a/components/Page.js b/components/Page.js deleted file mode 100644 index 5067360..0000000 --- a/components/Page.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { node } from 'prop-types' -import styled from 'styled-components' - -import Footer from './Footer' -import Navbar from './Navbar' - -const Children = styled.div` - align-items: center; - display: flex; - flex: 1; - flex-direction: column; - justify-content: center; - width: 100%; -` - -const Container = styled.div` - align-items: center; - display: flex; - flex: 1 0 auto; - flex-direction: column; - justify-content: center; - width: 100%; -` - -const Page = ({ children }) => ( - - - {children} -