# Project export: Culinary Chronicles

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: TreeHacks 2024
- Tagline: Eat like a king - literally.
- Devpost: https://devpost.com/software/culinary-chronicles
- GitHub: https://github.com/majdaloj/CulinaryChronicles
- Demo: https://www.postman.com/speeding-desert-805789/workspace/culinary-chronicles-treehacks-2024/collection/32897024-36ce58f4-874f-490d-a07a-6b147542f7af?action=share&creator=32897024
- Video: https://www.youtube.com/embed/xAl40oUdC9M?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Majda Lojpur (5 commits)

## Devpost submission (written by the team)

### Inspiration

✨ Writer's have the term writer's block when they are uninspired - but what about all us amateur cooks? Choosing what to make as a meal, everyday, three times a day, can get challenging! I, and many friends, find it difficult to come up with new meal ideas. To alleviate this issue, Culinary Chronicles was born. Culinary Chronicles aims to make food fun, by connecting friends of the present with major figures of the past (or present).

### What it does

💻 Get inspired by the diets of you favorite figures, either from the past or present! When you don't know what to eat, or simply want to try something new, use Culinary Chronicles to develop a customized meal plan based on your chosen persona (e.g., Marie Antoinette). In addition, you can export your meal plan as a PDF and share it with friends so that everyone can be part of the challenge. Culinary Chronicles aims to connect people of the present and past through food, making meal inspiration How I built it 🔨 Front-end was built with React.js Back-end was built with Node.js and Express.js, using OpenAI API Postman was used for testing: https://www.postman.com/speeding-desert-805789/workspace/culinary-chronicles-treehacks-2024/collection/32897024-36ce58f4-874f-490d-a07a-6b147542f7af?action=share&creator=32897024

### Challenges we ran into

⚠️ I really wanted to use Bun for the backend but it was not nice to my windows machine :_) Accomplishments that I'm proud of 🏆 It was my first solo hackathon, so I am proud of being able to finish a full-stack MVP in the short timeframe provided. I was able to execute the core features I had in mind. Seamlessly integrating OpenAI API in the backend What I learned 🏫 How to elegantly integrate OpenAI API into the backend: * Used model gpt-3.5-turbo * How to optimally set max_tokens to make the API calls faster without compromising quality Even though I wasn't able to use Bun, I did spend a considerable amount of time trying to get it to work, and as such learned quite a bit about this JavaScript Toolkit. Will definitely be making projects with it in the future!

### What's next

💭 An option for the meal plan to be read to the user in the AI generated voice of the major figure they chose (if voice is available) Comprehensive recipes listed alongside the meal suggestions Ability to save meal plans and make recommendations based on past major figures chosen by the user

## README (from the GitHub repository)

# Open Source Astrology

## HIGH-LEVEL SUMMARY
In this project, we propose an artificial intelligence recommendation pipeline to recommend matches with potential collaborators, open source projects looking for contributors and public data to start anew. We divide this challenging problem into three subproblems, including (1) collecting, cleaning and standardizing information from users, projects and data banks, (2) find the most common patterns for matching between data endpoints, and (3) break the patterns and use unlikely astrology matches to pair nodes together. By partitioning the process into subproblems, each of them can be more representative, and can be further used in future customizable matching schemes. The results demonstrate that sometimes staying in your comfort zone or only exploring what you think you want is limiting, and you future might be in (or written by) the stars!

## PROJECT DEMO
N/A

## FINAL PROJECT
N/A

## PROJECT DETAILS
### INSPIRATION ✨
The inspiration behind utilizing astrology as a paradigm for matching unlikely collaborators in open science projects stems from a profound recognition of the untapped potential that can emerge when we challenge conventional boundaries. Astrology, a centuries-old practice rooted in celestial alignments, offers a captivating metaphor for transcending the limitations of conventional thinking. By juxtaposing individuals and projects whose astrological profiles may not align conventionally, we introduce an element of serendipity and unpredictability into the collaborative process. This approach not only encourages diverse perspectives but also fosters creative synergy among collaborators who may otherwise remain undiscovered. In the realm of open science, where innovation and breakthroughs often emerge from unconventional connections and interdisciplinary collaborations, embracing astrology as a source of inspiration introduces an exciting avenue for harnessing the power of serendipity and unlocking new frontiers of discovery.

### WHAT IT DOES 💻
Introducing Open Science Astrology, a groundbreaking initiative poised to revolutionize collaborative efforts by harnessing the power of artificial intelligence. Our visionary project offers a meticulously designed recommendation pipeline that seamlessly connects individuals with compatible team members, aligns open source projects with enthusiastic contributors, and identifies relevant public datasets, all through the lens of astrology.

This transformative endeavor is structured around a three-fold approach:

Data Aggregation and Standardization: We meticulously gather, clean, and standardize information from diverse sources, including user profiles, project repositories, and data repositories. This meticulous data preparation forms the cornerstone of our recommendation system.
Pattern Recognition: Leveraging state-of-the-art machine learning techniques, we uncover prevailing patterns that underlie effective matches between disparate data sources. Our system identifies commonalities and connections that might elude conventional matchmaking algorithms.
Astrological Pairing: Going beyond conventional methodologies, Open Science Astrology employs astrological insights to create unique and unexpected pairings. By breaking free from conventional patterns and embracing unlikely astrological matches, we stimulate innovation and encourage novel collaborations.
By deconstructing this complex challenge into distinct subproblems, we not only enhance the representativeness of our recommendations but also lay the foundation for future customizable matchmaking solutions. Our results unequivocally demonstrate that remaining within your comfort zone or pursuing preconceived notions can be limiting. The future, as we reveal, might indeed be written in the stars.

Open Science Astrology is not just a project; it's a vision for a more interconnected, innovative, and harmonious future. Join us as we unlock the limitless potential of collaborative partnerships and data-driven discoveries, transcending traditional boundaries and expectations. The stars have aligned, and the possibilities are boundless.

### HOW WE BUILT IT 🔨
Open Science Astrology's frontend is built using React and the backend is created using Node.js. Design and prototype were first created on pen and paper and then replicated in React.

The databases used is a team-complied database sourced from NASA Open Data Initiative Github and NASA's Open Data Portal as well as LinkedIn listings to create our matchings off of.

### CHALLENGES WE RAN INTO ⚠️
As a team we have never used Chakra as a technology before. We also challenged ourselves to include an artistic aspect to utilize our team's full skill set to make a catchy jingle for our interface in hopes of attracting a larger userbase.

Additionally, reconciling the juxtaposition of astrology with scientific data presented a unique challenge. While astrology served as an inspirational metaphor for unconventional collaborations, bridging the gap between celestial interpretations and rigorous data science required careful consideration and fine-tuning. As a team it took a lot of deliberation to balance the appeal of astrological pairings and data-driven recommendations.

### ACCOMPLISHMENTS THAT WE'RE PROUD OF 🏆
By successfully completing this project, we would take immense pride in ushering in a new era of collaborative innovation within the open science community. Open Science Astrology represents a pioneering effort to break free from conventional matchmaking paradigms and embrace the unexpected. We would be proud to have provided a platform that encourages diverse perspectives, fosters creative synergies, and unlocks the untapped potential hidden within the stars.

As aspiring professionals of visible minorities, we're proud to have created a useful website that signifies our commitment to bridging the gap between tradition and technology and lies in catalyzing breakthroughs and discoveries that emerge from these unconventional collaborations.

### WHAT WE LEARNED 🏫
During the development of Open Science Astrology, we gained essential insights and lessons. In terms of soft skills we reaffirmed the significance of interdisciplinary thinking. Combining astrological inspiration with data science and artificial intelligence was an unconventional approach, but it taught us the power of merging diverse domains to foster creativity and uncover uncharted possibilities.

In terms of technological skills we learned:
- **data collection and management** by collecting, cleaning and standardizing data from diverse sources
- **machine learning techniques** looking for pattern recognition/node matching
- **cloud technologies** by deploying our project in the cloud environment

### WHAT'S NEXT FOR OPEN SCIENCE ASTROLOGY💭
The journey of Open Science Astrology continues to align with exciting possibilities. While astrology adds a cosmic touch, our real mission is to spark innovation by connecting diverse collaborators and projects. In the stars of our future, we see:

Refining Algorithms: We're fine-tuning our matchmaking algorithms to provide even more celestial connections.
User-Driven Enhancements: User feedback guides our journey, helping us customize and tailor recommendations.
Community Constellations: Building a vibrant community where researchers meet, collaborate, and reach for the stars.
Educational Stargazing: Illuminating educational paths for students and researchers to explore the cosmos of collaboration.
Scientific Validation: Collaborating with experts to validate our matchmaking magic (and how the stars hold the truth) and its impact on innovation.


What do you get when you put a Capricorn, Aquarius, Cancer and Leo in a group?

You get a "Zodiac Dream Team" – where Capricorn's practicality, Aquarius's innovation, Cancer's nurturing, and Leo's leadership combine to reach cosmic collaboration! 🌟😄


## Detected evidence (automated analysis)

Indexed codebase: 18 recognized source files, 30 KB.
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (24 of 24)

```
client/.eslintrc.cjs
client/.gitignore
client/index.html
client/package.json
client/README.md
client/src/api.js
client/src/App.jsx
client/src/components/Layout.jsx
client/src/components/Navbar.jsx
client/src/components/ProjectCard.jsx
client/src/components/ProjectContainer.jsx
client/src/constants.js
client/src/contexts/GlobalContext.js
client/src/main.jsx
client/src/pages/Home.jsx
client/src/pages/index.js
client/src/pages/projects.json
client/src/pages/SavedProjects.jsx
client/src/pages/Search.jsx
client/vite.config.js
README.md
server/.env
server/main.js
server/package.json
```

### Dependencies

- client/package.json: @chakra-ui/icons@^2.1.1, @chakra-ui/react@^2.8.1, @emotion/react@^11.11.1, @emotion/styled@^11.11.0, @react-pdf/renderer@^3.3.8, @types/react@^18.2.15, @types/react-dom@^18.2.7, @vitejs/plugin-react@^4.0.3, axios@^1.5.1, dotenv@^16.4.4, eslint@^8.45.0, eslint-plugin-react@^7.32.2, eslint-plugin-react-hooks@^4.6.0, eslint-plugin-react-refresh@^0.4.3, framer-motion@^10.16.4, jspdf@^2.5.1, react@^18.2.0, react-dom@^18.2.0, react-query@^3.39.3, react-router-dom@^6.16.0, vite@^4.4.5
- server/package.json: dotenv@^16.4.4, express@^4.18.2, openai@^4.28.0

### Recent commits (newest first)

- backend
- Project push - I am a solo team and I was working locally throughout the night - I can prove i worked on this code during the hackathon if there are issues with my one big commit (just saw the message about this) Thanks!
- index
- bun setup
- Initial commit

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

### server/package.json

```
{
  "dependencies": {
    "dotenv": "^16.4.4",
    "express": "^4.18.2",
    "openai": "^4.28.0"
  }
}

```

### client/package.json

```
{
  "name": "client",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "@chakra-ui/icons": "^2.1.1",
    "@chakra-ui/react": "^2.8.1",
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@react-pdf/renderer": "^3.3.8",
    "axios": "^1.5.1",
    "dotenv": "^16.4.4",
    "framer-motion": "^10.16.4",
    "jspdf": "^2.5.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-query": "^3.39.3",
    "react-router-dom": "^6.16.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@vitejs/plugin-react": "^4.0.3",
    "eslint": "^8.45.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.3",
    "vite": "^4.4.5"
  }
}

```

### server/main.js

```javascript
const express = require('express');
const OpenAI = require('openai');
const app = express();
app.use(express.json());

require('dotenv').config();
const openai = new OpenAI({
  apiKey: process.env.OPEN_AI_KEY, // Access the API key from environment variable
});

// Handle POST requests to /generateMealPlan
app.post('/generateMealPlan', async (req, res) => {
  try {
    // Parse input data from request body
    const { famousPerson, dietaryRestrictions, mealPlanDuration } = req.body;
    let prompt;
    if (
      mealPlanDuration === 'breakfast' ||
      mealPlanDuration === 'lunch' ||
      mealPlanDuration === 'dinner' ||
      mealPlanDuration === '1 day'
    ) {
      prompt = `I want to eat like ${famousPerson} for a day. Generate a meal plan with a complete recipes for ONE DAY me based on ${famousPerson}'s food preferences. I want to eat what ${famousPerson} liked to eat, historically recorded. Make sure the recipe does not have anything listed in my dietary restrictions: ${dietaryRestrictions}. The output should be of format: {"mealplan": {Day 1:{Breakfast: recipe, Lunch: recipe, Dinner: recipe}, Day 2, etc}.`; // Please include recipes for each meal as you list it!`;
    } else if (mealPlanDuration === '3 days') {
      prompt = `I want to eat like ${famousPerson} for 3 days. Generate a meal plan for 3 days me based on ${famousPerson}'s food preferences. Make the recipes compatible with my dietary restrictions: ${dietaryRestrictions}. The output should be of format: {"mealplan": {Day 1:{Breakfast: x, Lunch: x, Dinner: x}, Day 2, etc}. Make sure the recipe does not have anything listed in my dietary restrictions: ${dietaryRestrictions}. `;
    } else {
      prompt = `I want to eat like ${famousPerson} for 7 days. Generate a meal plan for 7 days me based on ${famousPerson}'s food preferences and meals they actually ate. Make the recipes compatible with my dietary restrictions: ${dietaryRestrictions}. The output should be of format: {"mealplan": {Day 1:{Breakfast: x, Lunch: x, Dinner: x}, Day 2, etc}. Make sure the recipe does not have anything listed in my dietary restrictions: ${dietaryRestrictions}.`;
    }
    // Generate message based on input data
    const message = {
      role: 'user',
      content: prompt,
    };

    // Request meal plan generation from OpenAI API
    const response = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: [message],
      max_tokens: 1000, // Adjust max_tokens as needed
    });

    // Extract generated meal plan from API response
    const generatedMealPlan = response.choices[0].message.content;

    // Send generated meal plan back as response
    res.json({ mealPlan: generatedMealPlan });
  } catch (error) {
    console.error('Error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

```

### client/src/main.jsx

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';

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

```

### client/src/App.jsx

```javascript
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ChakraProvider } from '@chakra-ui/react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { Home, Search } from './pages';
import Layout from './components/Layout';

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: '/search',
        element: <Search />,
      },
    ],
  },
]);

function App() {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      <ChakraProvider>
        <RouterProvider router={router} />
      </ChakraProvider>
    </QueryClientProvider>
  );
}

export default App;

```

### client/src/pages/index.js

```javascript
export * from './Home';
export * from './Search';

```

### client/vite.config.js

```javascript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    watch: {
      usePolling: true,
    },
  },
});

```

### client/index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

```

### client/src/constants.js

```javascript
export const SAMPLE_USER_ID = '6e1d4748-b8ad-4ac3-8360-079245890f59';

```

### client/src/api.js

```javascript
import axios from 'axios';
import { SAMPLE_USER_ID } from './constants';

const api_url = 'https://api-open-source-astrology.onrender.com/';
// const api_url = "http://localhost:3000/";

export const get_projects = async (search, user_id) => {
  const result = await axios.get(
    `${api_url}project?search=${search}&user_id=${user_id}&limit=9`
  );
  return result.data;
};

export const saveProject = async ({ projectId, userId }) => {
  const result = await axios.post(`${api_url}contributor/favorite`, {
    project_id: projectId,
    user_id: userId,
  });
  return result.data;
};

export const unSaveProject = async ({ projectId, userId }) => {
  const result = await axios.post(`${api_url}contributor/unfavorite`, {
    project_id: projectId,
    user_id: userId,
  });
  return result.data;
};

export const getCurrentUser = async () => {
  const userId = localStorage.getItem('userId') || SAMPLE_USER_ID;

  const result = await axios.get(`${api_url}contributor/${userId}`);

  return result.data;
};

export const getSavedProjects = async () => {
  const userId = localStorage.getItem('userId') || SAMPLE_USER_ID;
  const result = await axios.get(`${api_url}contributor/${userId}/favorite`);
  return result.data;
};

```

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