├── .nvmrc ├── client ├── .eslintrc ├── public │ ├── og.png │ ├── favicons │ │ ├── favicon.ico │ │ ├── apple-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── ms-icon-70x70.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ └── apple-icon-precomposed.png │ ├── fonts │ │ ├── CircularStd-Bold.woff │ │ ├── CircularStd-Book.woff │ │ ├── CircularStd-Black.woff │ │ ├── CircularStd-Black.woff2 │ │ ├── CircularStd-Bold.woff2 │ │ ├── CircularStd-Book.woff2 │ │ ├── CircularStd-Medium.woff │ │ ├── CircularStd-Medium.woff2 │ │ ├── CircularStd-BlackItalic.woff │ │ ├── CircularStd-BlackItalic.woff2 │ │ ├── CircularStd-BoldItalic.woff │ │ ├── CircularStd-BoldItalic.woff2 │ │ ├── CircularStd-BookItalic.woff │ │ ├── CircularStd-BookItalic.woff2 │ │ ├── CircularStd-MediumItalic.woff │ │ └── CircularStd-MediumItalic.woff2 │ ├── browserconfig.xml │ ├── manifest.json │ └── index.html ├── src │ ├── images │ │ ├── og.png │ │ └── favicons │ │ │ ├── favicon.ico │ │ │ ├── apple-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ ├── ms-icon-70x70.png │ │ │ ├── ms-icon-144x144.png │ │ │ ├── ms-icon-150x150.png │ │ │ ├── ms-icon-310x310.png │ │ │ ├── android-icon-36x36.png │ │ │ ├── android-icon-48x48.png │ │ │ ├── android-icon-72x72.png │ │ │ ├── android-icon-96x96.png │ │ │ ├── apple-icon-114x114.png │ │ │ ├── apple-icon-120x120.png │ │ │ ├── apple-icon-144x144.png │ │ │ ├── apple-icon-152x152.png │ │ │ ├── apple-icon-180x180.png │ │ │ ├── apple-icon-57x57.png │ │ │ ├── apple-icon-60x60.png │ │ │ ├── apple-icon-72x72.png │ │ │ ├── apple-icon-76x76.png │ │ │ ├── android-icon-144x144.png │ │ │ ├── android-icon-192x192.png │ │ │ └── apple-icon-precomposed.png │ ├── styles │ │ ├── Nav.js │ │ ├── Header.js │ │ ├── Footer.js │ │ ├── Button.js │ │ ├── index.js │ │ ├── Section.js │ │ ├── Main.js │ │ ├── media.js │ │ ├── theme.js │ │ ├── mixins.js │ │ └── GlobalStyle.js │ ├── components │ │ ├── ScrollToTop.js │ │ ├── icons │ │ │ ├── index.js │ │ │ ├── music.js │ │ │ ├── playlist.js │ │ │ ├── info.js │ │ │ ├── time.js │ │ │ ├── user.js │ │ │ ├── external.js │ │ │ ├── microphone.js │ │ │ ├── spotify.js │ │ │ ├── github.js │ │ │ └── loader.js │ │ ├── App.js │ │ ├── RecentlyPlayed.js │ │ ├── LoginScreen.js │ │ ├── Loader.js │ │ ├── Profile.js │ │ ├── TopTracks.js │ │ ├── TrackItem.js │ │ ├── Artist.js │ │ ├── Playlists.js │ │ ├── FeatureChart.js │ │ ├── Playlist.js │ │ ├── Nav.js │ │ ├── Recommendations.js │ │ ├── TopArtists.js │ │ ├── Track.js │ │ └── User.js │ ├── App.test.js │ ├── index.js │ ├── utils │ │ └── index.js │ ├── serviceWorker.js │ └── spotify │ │ └── index.js ├── .babelrc ├── .gitignore └── package.json ├── prettier.config.js ├── .env.example ├── .editorconfig ├── .eslintrc ├── .gitignore ├── README.md ├── package.json └── server └── index.js /.nvmrc: -------------------------------------------------------------------------------- 1 | 10.13.0 2 | -------------------------------------------------------------------------------- /client/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@upstatement/eslint-config/react" 3 | } 4 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@upstatement/prettier-config'); 2 | -------------------------------------------------------------------------------- /client/public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/og.png -------------------------------------------------------------------------------- /client/src/images/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/og.png -------------------------------------------------------------------------------- /client/public/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/favicon.ico -------------------------------------------------------------------------------- /client/public/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon.png -------------------------------------------------------------------------------- /client/src/images/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/favicon.ico -------------------------------------------------------------------------------- /client/public/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /client/public/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /client/public/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /client/public/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Bold.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Book.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Book.woff -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /client/public/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /client/public/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /client/public/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Black.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Black.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Bold.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Book.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Book.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Medium.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-Medium.woff2 -------------------------------------------------------------------------------- /client/src/images/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /client/src/images/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /client/src/images/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /client/src/images/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /client/src/images/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /client/src/images/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /client/src/images/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /client/public/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /client/public/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BlackItalic.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BlackItalic.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BoldItalic.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BoldItalic.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BookItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BookItalic.woff -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-BookItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-BookItalic.woff2 -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-MediumItalic.woff -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /client/public/fonts/CircularStd-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/public/fonts/CircularStd-MediumItalic.woff2 -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /client/src/images/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /client/src/styles/Nav.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | const Nav = styled.nav` 4 | margin: 0; 5 | `; 6 | 7 | export default Nav; 8 | -------------------------------------------------------------------------------- /client/src/images/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bchiang7/spotify-profile/HEAD/client/src/images/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /client/src/styles/Header.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | 3 | const Header = styled.header` 4 | margin: 0; 5 | `; 6 | 7 | export default Header; 8 | -------------------------------------------------------------------------------- /client/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | [ 4 | "babel-plugin-styled-components", 5 | { 6 | "displayName": true 7 | } 8 | ] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | CLIENT_ID=abcdefghijklmnopqrstuvwxyz 2 | CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz 3 | FRONTEND_URI=example.com 4 | REDIRECT_URI=example.com/callback 5 | LOGIN_URI=example.com/login 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@upstatement", 3 | "parserOptions": { 4 | "sourceType": "module" 5 | }, 6 | "env": { 7 | "browser": true, 8 | "node": true, 9 | "es6": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | .DS_Store 4 | 5 | .env 6 | .env.local 7 | .env.development 8 | .env.test 9 | .env.production 10 | 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | .vscode/ 16 | 17 | -------------------------------------------------------------------------------- /client/src/styles/Footer.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import theme from './theme'; 3 | const { spacing } = theme; 4 | 5 | const Footer = styled.footer` 6 | padding: ${spacing.base}; 7 | `; 8 | 9 | export default Footer; 10 | -------------------------------------------------------------------------------- /client/src/components/ScrollToTop.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const ScrollToTop = ({ children, location }) => { 4 | React.useEffect(() => window.scrollTo(0, 0), [location.pathname]); 5 | return children; 6 | }; 7 | 8 | export default ScrollToTop; 9 | -------------------------------------------------------------------------------- /client/public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /client/src/styles/Button.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import theme from './theme'; 3 | const { fontSizes } = theme; 4 | 5 | const Button = styled.button` 6 | font-size: ${fontSizes.base}; 7 | cursor: pointer; 8 | border: 0; 9 | border-radius: 0; 10 | transition: ${theme.transition}; 11 | &:focus, 12 | &:active { 13 | outline: 0; 14 | } 15 | `; 16 | 17 | export default Button; 18 | -------------------------------------------------------------------------------- /client/src/styles/index.js: -------------------------------------------------------------------------------- 1 | import GlobalStyle from './GlobalStyle'; 2 | import theme from './theme'; 3 | import mixins from './mixins'; 4 | import media from './media'; 5 | import Button from './Button'; 6 | import Header from './Header'; 7 | import Nav from './Nav'; 8 | import Main from './Main'; 9 | import Section from './Section'; 10 | import Footer from './Footer'; 11 | 12 | export { GlobalStyle, theme, mixins, media, Button, Header, Nav, Main, Section, Footer }; 13 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | 24 | src/**/*.css 25 | 26 | package-lock.json 27 | 28 | .vscode/ 29 | -------------------------------------------------------------------------------- /client/src/styles/Section.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import media from './media'; 3 | 4 | const Section = styled.section` 5 | width: 100%; 6 | margin: 0 auto; 7 | max-width: 1400px; 8 | min-height: 100vh; 9 | padding: 90px 0; 10 | ${media.tablet` 11 | padding: 0 0 90px; 12 | h2 { 13 | text-align: center; 14 | } 15 | `}; 16 | ${media.phablet` 17 | padding: 0 0 20px; 18 | `}; 19 | `; 20 | 21 | export default Section; 22 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './components/App'; 4 | import * as serviceWorker from './serviceWorker'; 5 | 6 | ReactDOM.render(, document.getElementById('root')); 7 | 8 | // If you want your app to work offline and load faster, you can change 9 | // unregister() to register() below. Note this comes with some pitfalls. 10 | // Learn more about service workers: http://bit.ly/CRA-PWA 11 | serviceWorker.unregister(); 12 | -------------------------------------------------------------------------------- /client/src/styles/Main.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import media from './media'; 3 | 4 | const Main = styled.main` 5 | width: 100%; 6 | margin: 0 auto; 7 | max-width: 1400px; 8 | min-height: 100vh; 9 | padding: 80px; 10 | ${media.desktop` 11 | padding: 60px 50px; 12 | `}; 13 | ${media.tablet` 14 | padding: 50px 40px; 15 | `}; 16 | ${media.phablet` 17 | padding: 30px 25px; 18 | `}; 19 | h2 { 20 | ${media.tablet` 21 | text-align: center; 22 | `}; 23 | } 24 | `; 25 | 26 | export default Main; 27 | -------------------------------------------------------------------------------- /client/src/components/icons/index.js: -------------------------------------------------------------------------------- 1 | import IconUser from './user'; 2 | import IconGithub from './github'; 3 | import IconExternal from './external'; 4 | import IconSpotify from './spotify'; 5 | import IconLoader from './loader'; 6 | import IconTime from './time'; 7 | import IconMicrophone from './microphone'; 8 | import IconPlaylist from './playlist'; 9 | import IconMusic from './music'; 10 | import IconInfo from './info'; 11 | 12 | export { 13 | IconUser, 14 | IconGithub, 15 | IconExternal, 16 | IconSpotify, 17 | IconLoader, 18 | IconTime, 19 | IconMicrophone, 20 | IconPlaylist, 21 | IconMusic, 22 | IconInfo, 23 | }; 24 | -------------------------------------------------------------------------------- /client/src/components/icons/music.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconMusic = () => ( 4 | 12 | 13 | 14 | ); 15 | 16 | export default IconMusic; 17 | -------------------------------------------------------------------------------- /client/src/components/icons/playlist.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconPlaylist = () => ( 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | 20 | export default IconPlaylist; 21 | -------------------------------------------------------------------------------- /client/src/components/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { token } from '../spotify'; 3 | 4 | import LoginScreen from './LoginScreen'; 5 | import Profile from './Profile'; 6 | 7 | import styled from 'styled-components/macro'; 8 | import { GlobalStyle } from '../styles'; 9 | 10 | const AppContainer = styled.div` 11 | height: 100%; 12 | min-height: 100vh; 13 | `; 14 | 15 | const App = () => { 16 | const [accessToken, setAccessToken] = useState(''); 17 | 18 | useEffect(() => { 19 | setAccessToken(token); 20 | }, []); 21 | 22 | return ( 23 | 24 | 25 | 26 | {accessToken ? : } 27 | 28 | ); 29 | }; 30 | 31 | export default App; 32 | -------------------------------------------------------------------------------- /client/src/styles/media.js: -------------------------------------------------------------------------------- 1 | import { css } from 'styled-components'; 2 | 3 | const sizes = { 4 | giant: 1440, 5 | desktop: 1200, 6 | netbook: 1000, 7 | tablet: 768, 8 | thone: 600, 9 | phablet: 480, 10 | phone: 376, 11 | tiny: 330, 12 | }; 13 | 14 | // iterate through the sizes and create a media template 15 | export const media = Object.keys(sizes).reduce((accumulator, label) => { 16 | // use em in breakpoints to work properly cross-browser and support users 17 | // changing their browsers font-size: https://zellwk.com/blog/media-query-units/ 18 | const emSize = sizes[label] / 16; 19 | accumulator[label] = (...args) => css` 20 | @media (max-width: ${emSize}em) { 21 | ${css(...args)}; 22 | } 23 | `; 24 | return accumulator; 25 | }, {}); 26 | 27 | export default media; 28 | -------------------------------------------------------------------------------- /client/src/components/icons/info.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconInfo = () => ( 4 | 13 | 19 | 20 | ); 21 | 22 | export default IconInfo; 23 | -------------------------------------------------------------------------------- /client/src/components/icons/time.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconTime = () => ( 4 | 12 | Time 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | 21 | export default IconTime; 22 | -------------------------------------------------------------------------------- /client/src/components/icons/user.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconUser = () => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default IconUser; 10 | -------------------------------------------------------------------------------- /client/src/components/icons/external.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconExternal = () => ( 4 | 5 | External 6 | 7 | 12 | 16 | 17 | 18 | ); 19 | 20 | export default IconExternal; 21 | -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /client/src/components/RecentlyPlayed.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { getRecentlyPlayed } from '../spotify'; 3 | import { catchErrors } from '../utils'; 4 | 5 | import Loader from './Loader'; 6 | import TrackItem from './TrackItem'; 7 | 8 | import styled from 'styled-components/macro'; 9 | import { Main } from '../styles'; 10 | 11 | const TracksContainer = styled.ul` 12 | margin-top: 50px; 13 | `; 14 | 15 | const RecentlyPlayed = () => { 16 | const [recentlyPlayed, setRecentlyPlayed] = useState(null); 17 | 18 | useEffect(() => { 19 | const fetchData = async () => { 20 | const { data } = await getRecentlyPlayed(); 21 | setRecentlyPlayed(data); 22 | }; 23 | catchErrors(fetchData()); 24 | }, []); 25 | 26 | return ( 27 |
28 |

Recently Played Tracks

29 | 30 | {recentlyPlayed ? ( 31 | recentlyPlayed.items.map(({ track }, i) => ) 32 | ) : ( 33 | 34 | )} 35 | 36 |
37 | ); 38 | }; 39 | 40 | export default RecentlyPlayed; 41 | -------------------------------------------------------------------------------- /client/src/components/icons/microphone.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IconMicrophone = () => ( 4 | 11 | Microphone 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | 19 | export default IconMicrophone; 20 | -------------------------------------------------------------------------------- /client/src/components/LoginScreen.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components/macro'; 3 | import { theme, mixins, Main } from '../styles'; 4 | const { colors, fontSizes } = theme; 5 | 6 | const LOGIN_URI = 7 | process.env.NODE_ENV !== 'production' 8 | ? 'http://localhost:8888/login' 9 | : 'https://spotify-profile.herokuapp.com/login'; 10 | 11 | const Login = styled(Main)` 12 | ${mixins.flexCenter}; 13 | flex-direction: column; 14 | min-height: 100vh; 15 | h1 { 16 | font-size: ${fontSizes.xxl}; 17 | } 18 | `; 19 | const LoginButton = styled.a` 20 | display: inline-block; 21 | background-color: ${colors.green}; 22 | color: ${colors.white}; 23 | border-radius: 30px; 24 | padding: 17px 35px; 25 | margin: 20px 0 70px; 26 | min-width: 160px; 27 | font-weight: 700; 28 | letter-spacing: 2px; 29 | text-transform: uppercase; 30 | text-align: center; 31 | &:hover, 32 | &:focus { 33 | background-color: ${colors.offGreen}; 34 | } 35 | `; 36 | 37 | const LoginScreen = () => ( 38 | 39 |

Spotify Profile

40 | Log in to Spotify 41 |
42 | ); 43 | 44 | export default LoginScreen; 45 | -------------------------------------------------------------------------------- /client/src/components/Loader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled, { keyframes } from 'styled-components/macro'; 3 | import { theme, mixins } from '../styles'; 4 | const { colors } = theme; 5 | 6 | const Container = styled.div` 7 | ${mixins.flexCenter}; 8 | width: 100%; 9 | height: 90vh; 10 | `; 11 | const dance = keyframes` 12 | from { 13 | height: 10px; 14 | } 15 | to { 16 | height: 100%; 17 | } 18 | `; 19 | const Bars = styled.div` 20 | display: flex; 21 | justify-content: center; 22 | align-items: flex-end; 23 | overflow: hidden; 24 | width: 100px; 25 | min-width: 100px; 26 | height: 50px; 27 | margin: 0 auto; 28 | z-index: 2; 29 | position: relative; 30 | left: 0; 31 | right: 0; 32 | `; 33 | const Bar = styled.div` 34 | width: 10px; 35 | height: 5px; 36 | margin: 0 2px; 37 | background-color: ${colors.grey}; 38 | animation-name: ${dance}; 39 | animation-duration: 400ms; 40 | animation-play-state: running; 41 | animation-direction: alternate; 42 | animation-timing-function: linear; 43 | animation-iteration-count: infinite; 44 | animation-delay: ${props => props.delay || '0ms'}; 45 | `; 46 | 47 | const Loader = () => ( 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ); 58 | 59 | export default Loader; 60 | -------------------------------------------------------------------------------- /client/src/components/Profile.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router } from '@reach/router'; 3 | 4 | import ScrollToTop from './ScrollToTop'; 5 | import Nav from './Nav'; 6 | import User from './User'; 7 | import RecentlyPlayed from './RecentlyPlayed'; 8 | import TopArtists from './TopArtists'; 9 | import TopTracks from './TopTracks'; 10 | import Playlists from './Playlists'; 11 | import Playlist from './Playlist'; 12 | import Recommendations from './Recommendations'; 13 | import Track from './Track'; 14 | import Artist from './Artist'; 15 | 16 | import styled from 'styled-components/macro'; 17 | import { theme, media } from '../styles'; 18 | 19 | const SiteWrapper = styled.div` 20 | padding-left: ${theme.navWidth}; 21 | ${media.tablet` 22 | padding-left: 0; 23 | padding-bottom: 50px; 24 | `}; 25 | `; 26 | 27 | const Profile = () => ( 28 | 29 |