# Project export: Write a Sentence, Get a Playlist

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 10.0
- Tagline: When you are feeling a specific emotion, no DJ or playlist has been able to comfort you. Let this change. Write a Sentence, Get a Playlist.
- Devpost: https://devpost.com/software/write-a-sentence-get-a-playlist
- GitHub: https://github.com/ainekeenan/calhacks23
- Team: 1 GitHub contributor(s) — ainekeenan (8 commits)

## Devpost submission (written by the team)

### Inspiration

Oftentimes, I am feeling a certain way that only a sentence can describe, not one emotion. Playlists never seem to be able to comfort me during this time. They seem to generic and based for someone else, not me. The Spotify DJ uses my top songs that I am sick of and jumps from emotion to emotion. I wanted to change this and allow for users to input a sentence, log into spotify, and get a playlist.

### What it does

At the moment, the application allows you to login to your spotify account, receive the spotify authorization code, use the code to receive the access token, and receive information about your account. Future features will allow for users to input a sentence on how they feel and will receive a playlist on spotify with that information.

### How we built it

I used React to create modular components for the front end and call the Spotify authorization url. That redirects to the request a backend API, written in express.js, which reads the code from the request, and asks for the spotify access token. After, the backend API uses the Spotify access token and authorization code to request information

### Challenges we ran into

One challenge is when I received the API code, and I stored it instead of sending it immediately to the backend. This made the access code invalid, causing a lot of issues.

### Accomplishments we're proud of

I am proud of figuring out OAuth2. OAuth2 requires you to go through many authorization steps, and makes it quite trick of what it will accept. Figuring out how to send all the pieces to each other correctly was something I am proud of.

### What we learned

I learned how to connect to the spotify API and honed in on my full stack application skills.

### What's next

Future features will allow for users to input a sentence on how they feel and will receive a playlist on spotify with that information.

## README (from the GitHub repository)

# calhacks23

Oftentimes, I am feeling a certain way that only a sentence can describe, not one emotion. Playlists never seem to be able to comfort me during this time. They seem to generic and based for someone else, not me. The Spotify DJ uses my top songs that I am sick of and jumps from emotion to emotion. I wanted to change this and allow for users to input a sentence, log into spotify, and get a playlist.

To run: 
cd into server
npm install 
npm start

cd into frontend
npm install 
npm start

enjoy!


## Detected evidence (automated analysis)

Indexed codebase: 19 recognized source files, 14 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- React (technology) — detected in the code

## Codebase structure (from repository index)

### Files (28 of 28)

```
frontend/.gitignore
frontend/package.json
frontend/public/index.html
frontend/public/manifest.json
frontend/public/robots.txt
frontend/README.md
frontend/src/App.css
frontend/src/App.js
frontend/src/App.test.js
frontend/src/index.css
frontend/src/index.js
frontend/src/pages/login.js
frontend/src/pages/token.js
frontend/src/pages/welcome.js
frontend/src/reportWebVitals.js
frontend/src/setupTests.js
README.md
server/app.css
server/app.js
server/bin/www
server/package.json
server/public/stylesheets/style.css
server/routes/index.js
server/routes/token.js
server/routes/users.js
server/views/error.jade
server/views/index.jade
server/views/layout.jade
```

### Dependencies

- frontend/package.json: @testing-library/jest-dom@^5.17.0, @testing-library/react@^13.4.0, @testing-library/user-event@^13.5.0, cors@^2.8.5, react@^18.2.0, react-dom@^18.2.0, react-router-dom@^6.17.0, react-scripts@5.0.1, spotify-web-api-node@^5.0.2, web-vitals@^2.1.4
- server/package.json: axios@^1.6.0, cookie-parser@~1.4.4, cors@^2.8.5, debug@~2.6.9, express@~4.16.1, http-errors@~1.6.3, jade@~1.11.0, morgan@~1.9.1, node-fetch@^3.3.2, spotify-web-api-node@^5.0.2

### Recent commits (newest first)

- Create README.md
- styling
- styling
- styling
- goes back
- gives you your info
- works for backend token show
- ok
- init

## Key source files (fetched from GitHub, selected and truncated for size)

### server/package.json

```
{
  "name": "server",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "axios": "^1.6.0",
    "cookie-parser": "~1.4.4",
    "cors": "^2.8.5",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "morgan": "~1.9.1",
    "node-fetch": "^3.3.2",
    "spotify-web-api-node": "^5.0.2"
  }
}

```

### frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "cors": "^2.8.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "spotify-web-api-node": "^5.0.2",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "react-router-dom": "^6.17.0"
  }
}

```

### server/app.js

```javascript
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
const axios = require('axios');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var tokenRouter = require('./routes/token')

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/token', tokenRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

```

### server/routes/index.js

```javascript
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

```

### frontend/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

```

### frontend/src/App.js

```javascript
import logo from './logo.svg';
import React from "react";
import {BrowserRouter as Router, Routes, Route} from "react-router-dom";

import './App.css';

import Welcome from "./pages/welcome"
import Login from './pages/login';
import Token from './pages/token'

function App() {
  const search = new URLSearchParams(window.location.search)
  const code = search.get("code");
  return (
    <div> 
      <Welcome /> 
      <Router>
        <ul>
          <li><a href = "/spotify">Login/Token</a></li>
        </ul>
        <Routes>
          <Route path = "/spotify" element = {code ? <Token code = {code}/>: <Login/>} ></Route>
        </Routes>
      </Router>
    </div>
  );
}

export default App;

```

### server/app.css

```css
*{
    text-align: center
}
```

### server/routes/users.js

```javascript
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

```

### frontend/src/setupTests.js

```javascript
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

```

### frontend/src/App.test.js

```javascript
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});

```

[9 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]