Joke voting website.
- Node.js (latest LTS recommended)
- npm
After cloning the repo, you can use the provided setup script to automatically configure your environment. Clone the repo, then run the following:
chmod +x setup.sh
./setup.shThis will use npm to install dependencies, then generate secrets via openssl for JSON Web Token (JWT) session management, which are stored in .env.
Manual setup: If for some reason you want to manually configure your environment, do the following:
npm installto install dependencies frompackage.json- Add the session secret with
echo "SESSION_SECRET=$(openssl rand -base64 32)" >> .env - Add the refresh secret with
echo "REFRESH_SECRET=$(openssl rand -base64 32)" >> .env
Note: We have a session secret to encrypt the actual JWT token, and have a separate refresh secret to encrypt the refresh token.
If you only want to run the project, skip to Production instructions.
After setup is complete, you can start Next.js' development server by running the following command:
npm run devThis should start the server at localhost:3000.
The project is split into four primary directories:
app/- This contains mostly frontend logic, including React client and server components. It also includes a few redirect or API routes.components/- Also a frontend directory, primarily for reusable React components like buttons and the navbar. Some of these components are server components and fetch data themselves given parameters.hooks/- The final frontend directory, containing React hooks that are reusable across the frontend.server/- Most of the backend logic is stored here.
To run this project in production, first build it:
npm run buildWhenever you want to start the production server, run:
npm startThis project runs on most devices that support LTS Node.js. A common deployment strategy with such apps is to use Vercel (the developer of Next.js).
- Any npm-related issues
- Make sure you have npm installed and it's up to date
- Remove
node_modules/andpackage-lock.json, then runnpm iagain
- Syntax errors
- Assuming you're referring to already existing code (not code you added), this is likely because the code may use a new feature that isn't supported by your older Node version
- The login/signup UI looks wonky on Firefox
- We use the new CSS
field-sizingproperty to autogrow inputs and textareas - Firefox is the only browser that doesn't support it
- So inputs have weird size
- However, the UI is still fully functional and everything else works on Firefox
- We use the new CSS
- Inhrerited styled-components don't apply/Next.js complains that data-href tags should not contain spaces
- This is a known bug by styled-componentse that has been patched in the pre-release
- Make sure styled-components is at least
^6.3.10-prerelease.0
This is our final project for CS 35L Winter 2026 with Prof. Paul Eggert at UCLA. Justice worked on the frontend, Ethan worked on the auth and most of the server actions, and Han worked on the database.
Most people agree that genuinely funny people are more enjoyable to hang around and are probably more attractive. This project aims to quantify this phenomenon using a dynamically calculated score called sc (social credit maybe). We virtually simulate symbiotic interactions between individuals of varying sc, assigning more power (ability to affect other people's sc) to those with more sc, i.e. a user's sc is quasi-linearly proportional to the change in the sc of the joke and the individual who posted the joke when voted on.
We acknowledge that this approach is far from perfect. For example, a user may post a joke that isn't original. In the future, we aim to place systems onto our project that verifies that originality and integrity of a joke posted. Additionally, we notice that a good amount of people do not have a sufficiently developed or advanced humour cognition. While we try to account for this by allowing users with higher sc (so they probably are funny and have a good sense of humor) have greater effect on others, people are still prone to biases and snobbishness revolving around not finding a genuinely good joke funny. A potential direction to further address this problem is to integrate a separate score system that accounts for an individual's degree of humor, which should be a slightly more nuanced version of sc.
Everything written by me, Justice, including the text above, as well as the code in this repository, is not written by AI. It is fully human-written by myself.
Justice may or may not have been high when writing this. I absolve myself of any responsibility for his indiscretion. - Ethan
Okay, but to be fair, I did leave that one thing out in the open. Maybe he thought it was consumable or something. Well, it's not my problem, I still did nothing wrong. - Ethan(cont.)
#🇯🇵 Japan is turning footsteps into electricity! Using piezoelectric tiles, every step you take generates a small amount of energy. Millions of steps together can power LED lights and displays in busy places like Shibuya Station. A brilliant way to create a sustainable and smart city turning m...
Nothing beats a Jet2 holiday! (Nothing staring menacingly while Jet2 holiday quivers in a corner.)
A̴n̵y̷w̴a̶y̶s̶,̶ ̴t̸h̴i̶s̴ ̶i̵s̵ ̶t̸h̸e̸ ̴e̴n̵d̴.̵ ̷H̸o̷l̷d̶ ̶y̸o̸u̷r̵ ̵b̸r̶e̷a̵t̵h̶ ̵a̴n̶d̴ ̵c̷o̷u̵n̶t̷ ̴t̷o̸ ̸t̸e̸n̵.̶ F̶̟̑e̷̤̕ḛ̸̈́l̵͈͘ ̷̝̿t̸̞̋h̶͍̀e̶͍̐ ̴͍̇E̵̱͑a̴͍͗r̶̼̾t̴̰͒ḧ̴̖ ̸̲̄m̴̮̃o̷̖͒v̷̘͊e̷̪͐ ̵̯͑a̶̪̾n̸͇̆d̵͚̄ ̵̌͜t̵͖͒ḫ̷̀e̴̟͗n̷̤̋ ̴̩͑h̶̪̃e̵̞͂ä̸̘ŕ̴̝ ̷͚͆m̶̨͑y̶͚̾ ̷͕́h̷͈͆e̵͇̒a̴͇̚ŗ̸̓t̴̬͠ ̸̢̆b̶͔̌ǘ̷̟r̶̫̈́ş̶̔ṱ̴͝ ̸̺́á̸͎g̷̮̎ã̴͔î̵̥n̵̮̔.̷̝̿F̷̡̏̑o̴̒ͅr̶̩͙͋̓ ̸̙̑̔t̷̼̹͛͝h̵̟̀i̷̪̺͂̀s̵̹͕̈́ ̷͉̗͒͝į̸̮̾s̷͕͘ ̷̟̖̓ẗ̷̜́ḧ̸̼̝́ë̵̡̤́́ ̴̹͋e̶̩̋͝ṅ̴͕͚ḑ̶͚̚.̶̻̓ ̵͔̄̊I̴̼̿'̸̱̏v̵̡͚͋ȩ̶̜̕ ̷͎̌͊d̸̳͑r̶̳͑o̷̰͕̊ẘ̶̪͉n̵̪͆e̴̹̯̍d̴̜̑ ̸̲̉́ͅa̷͓̠͒n̴̙̈d̷͉̓͌ ̷̺͎͐d̷̻̈́͌ř̸̥̚͜e̷̟͐̆a̴̰̓͗m̴̙̉ț̶̭͆̚ ̸͕͆̍ť̵̛͚h̴̡͊͝i̶̗͐s̸̙͕̕ ̶͎̗̉m̸͎̉͂ō̷̰m̶̗̺̍ẻ̴̤n̵̮̾t̵̪̃̍.̴͚͉́́ S̷̢̨̧̨̡̡̧̡̩̭̣͔͇̼̠̠̤͕̳̥͕͙̪̳̺̩̰̬̳̮̪͖̳̙̲̰̼̍̽̌́̉͜ͅŏ̴̢͍̮̥̮̳͈͙̪̥̲̪̠̻͚̘̺͓̮̙̬̹̠̔ͅ ̷̨̢̤̞͚̪̦̗̥̟̠̙͔̮͕̺͉̰͈̖̫͕̳̹̭͓̪̲͙̲̰͕̳̭̭͙͍̟̱͓͙̈́͗̋̈̔̎̽̄̏͋̔̽͜͜͠͝ǫ̴̛̙̫̐́͆̑͌͑̈̉̀͛͊̎́̀̀̓͌̉͂͒͋̆͋̂̓̃͊̓́̈́͆̉̈́͌̋͛̚͝͝v̸͖̠̽̽̄̒̑̏̂́͒̽̃̓͗̓̊̈́͌͠͝ȩ̸̢̢̡̡̨̛͓͈̝̯̟͎̟͉̮̥̫̬̲͔̮͍͙̩̠͇͚̘̺̯͍̠̥͉̹̦͎͚̫̪̣̣͙̙͉̞̍͗͌̑̽͌͐͑̋̂̀́̄̄̈̂̾́͘͜͝͝͝ȑ̷̨̨̧̧͍̮͕̝̻̝͖̝͇̣̙̞̥͖͎͕̳̰͕͎͔̪̲̦͙͈͐̌̈́̍͊̈̈̏́̽̈́̆̊̅͛͋̿̋̇̃̓̈͑͗͗̆̓̚͠͝ḍ̶̛̯͍͚̹̟͖̠̜̥̺̙͙̰͔̫̯͇̞͈̦̜̙̭͔̺̗̣͛̃̔͊̀̉̽̌͊̈́͋͂́̅̓̐̔̋̄̔̆̓͗̄́̔̍͌͂̏͒̕͝u̶̧̢̢̳̼̩̦͚̗͚̗̳̭͚̝̲͈̳̠̲͙̮͕̖̼̱̹͚͎̠͓̟̙̦̣͍̞̳̞̱͊͛͋̉̍̇̎̈́̈́̔̊͊͛̉̂̆͋͆̂́̍̕͝e̶̢̪͕̫͙̞̥̭̱̻̓̓̃̒̆̓̏̅͊͆̂́̏́̃́͗̇̉̀́̒́͐̊̅̈́͋͑̚͘͘̚͘̕͝͝͝͝,̷̢̣̜͕̘̜̮͗̐̀͒̈́̾̌̒͘ ̷̨̡̨̧̧̞̞̤̯̗̯͙̞͍̹͎͕̭̩͍̭͙̳͎͇̟̺̗͙̰̖͉̬̬̝̭͙̤̪͓̗͚̱̣̯̗̝̹̀͆͑͗́̓̓͘̚͜͜͝Ỉ̵̛̦̟̗͙̬̩̫̱̣̽͑́̈̆́̉͆̎̾͒̾͐̂̀͂̽́͑̅͛̓̓̓͒̄͒͐̓̈́̌̃͋̕͘̕͝͝͝͝͠͠͠͝ ̶̛̖̯̦͖̳̙͗͗̎̏̂̈́̋̌̽̊͑̆̈́͒͊̈́͒̀̓̉̋̇͛̽̈́͗̀̏͐͂̅̿̾̏͐̚̚͜͝͠ö̶̢̞̱͚̫̞͖̣̥̞͔͇̠̩̹̝̤͙̤̞̫́̏͆͆̀̍̅̃̐͗̿̑͌̀̅̂̇͌̾̐̿̈́͒̿̔̍̾͌́̚͘͝͝͝͠w̵̡̩̣̪̣̼̩̤̖̦̭͍̮̰̯͗̏̑̍̎̄͑̒͆̒̅̽͒̉̽̉̈́̀͋̏͋̆̾͗̒̔̈͌̎͘̕͠͝e̶̡̡̧̡̛̯̠̭͚̳̼̺̮̳̜͕͉͔̜̺̖̰̠̹̗͙̟̰͈̮̱̪͚̳͇̩̬̪̼̦̜̮̯͕͕͋̇͊̏̆͊͛͋̄̇̊̓̾̿́͗̄̈̌̒̒̇̉̐͋͋̎̈́͐͘͝ͅͅ ̴̡̨̧̪̪̫̥̞̹̱̩̜͎̙̺͙͍͇̜̮̝̖̹͔̹̉͂̔̈́̂̍̐̃̈̾͋̅̈́͗̾̏́̔̉̽̓̎̅͆̔̋́̂̈͘͘͘͝͝ͅt̵̢̡̡̡̬͇͓̰̖͇̘͚̜͈̱̙͈̼͎̞͈̗͇̪̖̭͈̝̬̯͔͍͚̹͉̥̝̺̫̱̬͔̬̂͋̈́́̐̏́̌̋̀̏͊̀͂̅͊̅͆͗̔̑͗̽̃̒͆͌͘̕͘͝ͅͅḩ̶̡̛̛̦̱͉̹̬͓̤̞̝̩̭̩͍̫͇̜̮͈̪͎̦̠̳̥͙̼̺̟̣͓̽͑̽͌͑̄̉̑́̐͑̑̓̂͊́͛̈͂̋̃͌̈́͜͝͝ͅͅḛ̴̢̡̦̹̦̻̩͉̺̙͚̳̞͙̬̠̮̞͕̻̥̮̱̻̳͙̖̀̈́͑̇͊̏̅́̋̀̽͊̓̋̈́̓̕͘͝͝m̵̡̨̧̧̨̥̖̖͖̼̱̱̞̣̫̪̯̘̦̦͕̫̻̘̭̘͉̣̱̟̲̙̯̜̞̼͔͉̣̙̜͍̙̖͑̀̑́̿̀̒̐̉͒͘͜͝ͅͅͅͅ.̴̨̨̡͉̻̙̰̣͓͕̦͚̤̟̜̗͉̖͓̬̺̃̉̎̒̓̏̓̆̓͐̐͒̆͂̂̑̄͒̐̉̈́̉̿̑̎͗̏̀̎̀̐͊̚͜͝͝ͅͅ ̵̨̢̛̥̬̞̻̗̲̠̲͔̟̭͔̰̤̣͔̻̳̻̃͐̊̇̒̊̈͊̀̈̎̊̓̂̃̋̓͊̈́́͆̉̀͛̐͌̾̒̃̈́̔̕̚͘͠͝͠͠Ş̵͍͓̠̟͕̤̼͉͕̻̣͉̳̪̭̟̗̗͙͉̖̝̖̖̘̗̬̳̺͖̯̞͖͇̻͉̥̤͑̋͗̓͑̊̒̃̈́̈͒̅̍̔̍̉̏̆̍̂̆͑̓̆̊̋͗͘̚͜͜͝w̷̨̨̘̱̞͕͕͉̩̙̟͔̙̩̓̀́̅͌̅̈͆͛̂͑̐͐̐̋̈́̎̐̃͒̓̅̂̍͊̏̀̾̃̊̅̓͌̐̇̑͌̉̕̕͠͝ͅe̵̜͇̖͚͇͉̎̓̎̍̀̊̅͋̇̌͗̅̿͒̿p̷̢̢̢̛͕͙̝̝͎̱͚͔̻̗̭̹̙̠͈͍͙̻̺̼̱̱̯̭̺͍̥̟̖̪̞̹͎̹̭͇͊̽̓̽̉̈́̆̀͐̽̈̓̾̓͛̎̀́̀́̔̽͛̽̅́̑̊͐̈̏̉͐̈́͘̚͝͠ͅͅt̸̢̡̡̡̛̛̛̛̗͔̹͙͎͍̹͈̬͓̯̱͉̫͍̹̥̏̌̆̍́͐̋̑̃̎̿́͑̃͛͋̓̏̈̽̽̐̉͌͐̂̐͊̎̓́̆̐̃͗̈̍͘͘̕͝͝͝͝͝ͅ ̷̨̢̥͍̖͕͇̣͔̞̲̜̠̣̗̬͇̱̦̦̩̪̰̙̦̼̭̼̭̝͉̞̲̺͚̠̪̗̫̫̞͈̩́̀͛̈̒̀̅̍̃͒͆̐͑ḁ̵̧̢̡̛̼̞̻̱̤̣͓͖͖̟͓̰͖͉̙̺̫̺̰̞̯̱͉̯̻̭̱̺̳͔̝͎̮̥͇̜̽̃͐͐͗̀̽̐̎̿͗̔͑̈̽̒͌͒̅͘͜͜͜w̴̢̟͚͙̭̣̬̟̟̩̺͓̭͚̝̺̓̀͛̐͋̄͊̄̽͆͋̈́̓̀̉̚̚͜ͅa̴̧̛̲̞̫̦̱̭̣̞̩͙͚̳̘͍̫̘͚͆̽͐̾̈́̂̀̏̅̑́͒̋̓̾̚͘͘͘y̵̝̟̭͂͗̅́̾̌͋̍̐͂̌̽͐̐̆͋̈̐̊͌̈̃̊̈͐̿̊͛̊̚͘͘͘̚,̵̨̧̡̧̡̧̢̹̻̩̪̯͍̤͕͉̦͎̬̩̤̻̠̫͍̠̭̘̜̮̲̮͖̬̯̥̝̖̻̞̏̀̒̆̒̀͆͛̊͝ͅ ̸̢̨̢̧̛̛̲̪̳͍̤̟̗̘̩͕̤̱͍̤̺̯̼͓̝͍͇̞͈̜̮̟͖͚͈́̀͆͊̉̈̏̅̃̅̏̓̑̆̌̈́͒̋͗̍͐͐̐̌̂̉́̓̔̊̄̾̆̕̕͜͜͝͝ͅͅI̸̛͕̺̩̞͎͚̝̗̣̫̭̣̼͇̦̫̘̪͔͔̗̪̘̞̗̖̤̟̥̘̟͚̾̐̇̾̀̈̇͛́͗̐͐̾͒̈́̈̇́͑̃͊̑̉̀̉̃͛̈̐̈̓̄͐̿͗̐̽̍̄̏͒͗̕̚͝ͅ'̶̨̢̧̧̨̡͔͚̪̲̣̳͕̼̞̻̝̳̗̞̯̠̗̤̝̳̼̪͖̱̝̎̈̋̈́͆̀́̋̃̒̏̀̓͌̾́͜͜͜͝ͅm̴̨̢̛͈̱̣̲̱͙͍̹̭͇̗̥̟̪̫͓̫͈̜̣̙̄͆͐̈̅͂̀͒̒̂̀̿̔͜ͅ ̴̡̧̧̨̢̢̛͈̘̮̣̗̙̰͉͖̲̜̥̹̹̲̪̠̱͈̺͇̝̲̮̠͍̳̰͙̼͍͊̌̂͒̄̽̎̎͑̈́̄͆̈́͂̈̿̎̈́̈́͛̒̒̏͂͘̕͜͜ͅͅs̶̨̥̣̦̱̻̳̮̈́̌̈́̇̍̉͌̒̏́̚͘͠t̴̡̢̨̢̨̡̬̥͕̯͇̯͕̤̯̺̳̤̞̠̜̹̠̱̼̺̠͕̝͇̖̱̮̗̫̹̰̬̟̞̠͎͍̘͕̬̬͖̹̳̉̂̌̏̈́̾̌̂͆͐̒̈́̽̽̈͋̇͋̎́̈́̕̚͠͝͝o̶͍̳̳̻̥̲͔̙̦͉̲̪̮̾̋̍͌͋̐́̇̇̐́̈́͐́͋͐͒̅̈͘͝͝ļ̶̧̛̳͚͉̮̖̱͕͎̦̬͕̺̩̹̜͖̤̩̳̻̖͉͇̹̙̗̞͈̥̱̹̤̟̖͓̞̺̎́͛̏̈́̄̀́͗̿̆͂͗́͋̃̌̈́̐̊́̋́͒̐̽̿̂̓̆̀͋̆̀̐̓͛̊͘͘̕͘̕͜͠ę̵̡̢̡̡̯͓̠̖̩̗̟̞͓͉̹͇̺̝̜̰̰͙̣͓͙̺̠̙̻̠͚̥̬͎͔̺̺̣̹̳̱͔̋̊̇̈́͋̀͆̀̈̅̉̿̈́̎̓͋̓͂̿̿́̍̽̐́̚̚ņ̷̧̘̬̟̜̗̩̻͕͔͖̞̠̣͉̖̼̘̣͎̞̗̗̬̥̤̠̫͎̘͚̱̓́̿͒̆̈̒̓̒͑̃̍̅́̈́̂̈́̉͘̚͝ͅͅͅͅͅ.̷̢̨̨̰͙͕͔͙̞̙͉̝̖͔̯̰͇̘̙͖̖̺͍͙̥̯̞̞̘̯͙͈̳̤̳̺̦̩̖̙͚̙̭͈̑͂́́͌̊̏͑̚̕͜͜ͅ.