# Project export: FaceToFace

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: Content-driven lifestyles absorb people away from in-person interactions. Our goal is to leverage technology to lower the barrier of scheduling, in turn enabling more meaningful physical meetings.
- Devpost: https://devpost.com/software/hum-ex-scheduler
- GitHub: https://github.com/steeevin88/schedulerAI
- Demo: http://www.hum-ex.tech/
- Video: https://www.youtube.com/embed/GlM_UcpLH5E?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — steven (27 commits), Luceium (27 commits), mikieyx (24 commits)

## Devpost submission (written by the team)

### Inspiration

Modern calendar applications are frequently used to manage, track, and store an individual's schedule(s); however, there is a proper system to link schedules amongst friends, making it a hassle to coordinate shared events with one another.

### What it does

Our application allows users to coordinate events with friends by allowing them to upload personal .ics files from modern calendar applications (ex. Google Calendar). Users can register for accounts and add friends to access their availabilities and schedule (in-person) meetings. Additionally, users can be recommended events based on their preferences and their (stored) meeting history.

### How we built it

We created a Next.js 13 application, using Tailwind to style our webpage. We integrated CockroachDB using the Prisma ORM to manage user administration (register, login). To both find available meeting times and recommend potential events between users, we queried the users' event and meeting history and sent it to TogetherAI's

### Challenges we ran into

We ran into various issues in setting up the CockroachDB database using the Prisma ORM, as our groupmates only had experience with nonrelational database management systems (ex. MongoDB). A lack of documentation for the new Next.js 13 with our technologies combined with a need to translate and parse .ics files and unfamiliarity with TogetherAI's API, caused many roadblocks along the way to our final project.

### Accomplishments we're proud of

We were able to implement all of the features that we originally planned, resulting in a minimum viable product that highlights our projects' main premises. We had a discouraging slow start to project development, so we're all extremely proud of our turnaround in creating a functional web application with previously foreign technologies.

### What we learned

The greatest takeaway for our group was the importance of technology documentation. A lot of our early struggles were eventually solved once we understood the documentation, leading to lots of time wasting that could have been avoided.

### What's next

We'd like to implement more direct connections to modern calendar applications, specifically Google Calendar, given the availability of Google Calendar's API. Additionally, we'd like to rework the application's UI, creating a more visually appealing interface for users to streamline their schedules around.

## README (from the GitHub repository)

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
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## 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/new?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.


## Detected evidence (automated analysis)

Indexed codebase: 22 recognized source files, 34 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- PostgreSQL (technology) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (27 of 27)

```
.gitignore
app/api/calendar/route.js
app/api/friends/route.js
app/api/plan/route.js
app/api/preferences/route.js
app/api/users/route.js
app/friends/page.tsx
app/globals.css
app/layout.tsx
app/libs/prisma.js
app/login/page.tsx
app/page.tsx
app/plan/page.tsx
app/signup/page.tsx
app/uploadcalendar/page.tsx
next-env.d.ts
next.config.js
package.json
postcss.config.js
prisma/migrations/20231028091146_init/migration.sql
prisma/migrations/20231028163338_update/migration.sql
prisma/migrations/migration_lock.toml
prisma/schema.prisma
public/components/Navbar.tsx
README.md
tailwind.config.ts
tsconfig.json
```

### Dependencies

- package.json: @next/font@^14.0.0, @prisma/client@^5.5.2, @types/node@^20, @types/react@^18, @types/react-dom@^18, autoprefixer@^10, axios@^1.6.0, eslint@^8, eslint-config-next@14.0.0, next@14.0.0, node-ical@^0.16.1, pg@^8.11.3, postcss@^8, prisma@^5.5.2, react@^18, react-dom@^18, tailwindcss@^3, typescript@^5

### Recent commits (newest first)

- Merge pull request #17 from steeevin88/michael3
- Merge branch 'main' of github.com:
- finished AI API requests
- Merge branch 'main' of github.com:steeevin88/schedulerAI
- Updating
- Merge pull request #16 from steeevin88/michael3
- resolve small conflict
- Merge branch 'main' of github.com:steeevin88/schedulerAI into michael3
- Merge branch 'main' into michael3
- begin callAI function
- added preferences endpoint
- finished logic
- changed styling
- more logic for union
- cleaned file directory
- added home icon to navbar
- added sign out to navbar
- Merge pull request #15 from steeevin88/mau
- Merge branch 'main' of github.com:steeevin88/schedulerAI into michael3
- Merge branch 'main' of github.com:steeevin88/schedulerAI into mau

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

### package.json

```
{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@next/font": "^14.0.0",
    "@prisma/client": "^5.5.2",
    "axios": "^1.6.0",
    "next": "14.0.0",
    "node-ical": "^0.16.1",
    "pg": "^8.11.3",
    "prisma": "^5.5.2",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10",
    "eslint": "^8",
    "eslint-config-next": "14.0.0",
    "postcss": "^8",
    "tailwindcss": "^3",
    "typescript": "^5"
  }
}

```

### app/layout.tsx

```typescript
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
import NavBar from '../public/components/Navbar'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <NavBar/>
        {children}
      </body>
    </html>
  )
}

```

### app/page.tsx

```typescript
// Main page hosting the calendar view
"use client";

import { useState } from 'react'

const page = () => {
  const [calEvents, setCalEvents] = useState(null);
  const usernameCookie = document.cookie.match('(^|;)\\s?username\\s?=\\s?([^;]+)');
  const username = usernameCookie ? usernameCookie[2] : null;
  
  if (!username) {
    window.location.href = "../login"
  }
  const myReq = new Request(`/api/calendar`, {
    method: "GET",
    headers: {
      "email": `${username}`
    }
  });

  async function loadCalendar() {
    if (calEvents) {return;}
    const response = await fetch(myReq);
    setCalEvents(await response.json());
    console.log(calEvents);
  }
  function delay(ms: number) {
    return new Promise( resolve => setTimeout(resolve, ms) );
  }

  delay(1000).then(() => {
    loadCalendar();
  });

  type Event = {email: string, end_time: string, event_name: string, id: number, start_time: string}

  function formatTime(time: string) {
    let indT = time.indexOf('T');
    let indDot = time.indexOf('.');
    let date = time.substring(0, indT);
    let hour = time.substring(time.indexOf('T')+1, indDot-3);
    return `${date}\n${hour}`
  }


  return (
    <div className='flex flex-row flex-wrap'>
        {calEvents && calEvents.map((event: Event) => {
            return (
                <div className="rounded-xl bg-blue-200 p-10 m-5 flex flex-col justify-center items-center">
                    <h1 className="text-4xl font-lato">{event.event_name[0] == ':' ? event.event_name.substring(1) : event.event_name}</h1>
                    <h2 className="text-2xl font-lato">{formatTime(event.start_time)}</h2>
                    <h2 className="text-2xl font-lato">{formatTime(event.end_time)}</h2>
                </div>
            );
          })
        }
    </div>
  )
}

export default page
```

### app/friends/page.tsx

```typescript
"use client";

import { useState } from 'react'

const Page = () => {
  const [friendEmail, setFriendEmail] = useState('')
  const [error, setError] = useState('')

  const onSubmit = async (e: any) => {
    e.preventDefault()

    // Construct the fetch request
    const request = new Request(`../../api/friends`, {
      method: "POST",
      body: JSON.stringify({"email": friendEmail})
    });

    // Make the fetch call and handle the response
    const response = await fetch(request);
    console.log(response)
    const data = await response.json();
    setError(data.message)
  }

  return (
    <>
        <section className='text-center'>
            <h1 className="my-7 text-7xl font-lato">Add a Friend</h1>
            <form onSubmit={onSubmit}>
                <div>
                    <input type='email' className='p-5 bg-blue-100 w-[50%] my-3 border' id='email' name='email' 
                    placeholder='Enter the email address of your friend' onChange={e => setFriendEmail(e.target.value)}/>
                </div>
                <div className='p-5 w-[50%] bg-yellow-200 rounded-xl my-3 mx-auto shadow-2xl justify-self-center'>
                    <button type='submit' className='justify-self-center'>Submit</button>
                </div>
                {error && <p>{error}</p>}
            </form>
        </section>
    </>
  )
}

export default Page
```

### app/login/page.tsx

```typescript
"use client";

import { useState } from 'react'
import Link from 'next/link'

const page = () => {
  const [loginInfo, setloginInfo] = useState({
    email: '',
    password: '',
  })
  const [error, setError] = useState('')
  const [errorLink, setErrorLink] = useState('')

  const { email, password } = loginInfo;

  const onChange = (e: any) => {
    setloginInfo((prevState) => ({
        ...prevState,
        [e.target.name]: e.target.value
    }))
  }

  const onSubmit = async (e: any) => {
    e.preventDefault()

    const userData = {
      email, 
      password,
    }

    // Construct the fetch request
    const request = new Request(`../../api/users`, {
      method: "GET",
      headers: {
        "email": email,
        "password": password,
      },
    });

    // Make the fetch call and handle the response
    const response = await fetch(request);
    try { // error (has JSON response)
      const data = await response.json();
      setError(data.message)
      if (data.link) setErrorLink(data.link)
    } catch {
      window.location.href = "../../"
    }
  }

  return (
    <>
        <section className='text-center'>
            <h1 className="my-7 text-7xl font-lato">Login</h1>
            <form onSubmit={onSubmit}>
                <div>
                    <input type='email' className='p-5 bg-blue-100 w-[50%] my-3 border rounded-md' id='email' name='email' 
                    value={email} placeholder='Enter your email' onChange={onChange}/>
                </div>
                <div>
                    <input type='password' className='p-5 bg-blue-100 w-[50%] my-3 border rounded-md' id='password' name='password' 
                     value={password} placeholder='Enter your password' onChange={onChange}/>
                </div>
                <div className='p-5 w-[50%] bg-yellow-200 rounded-xl my-3 mx-auto shadow-2xl justify-self-center'>
                    <button type='submit' className='justify-self-center'>Submit</button>
                </div>
                {error && (errorLink ? <Link href={errorLink} className='text-blue underline'>{error} Click here for Sign Up</Link> : <p>{error}</p>)}
            </form>
        </section>
    </>
  )
}

export default page
```

### app/signup/page.tsx

```typescript
'use client';
import Link from 'next/link';
import { redirect } from 'next/navigation'
import React, { useState } from 'react'
// const ical = require('node-ical');

const Page = () => {
  const [error, setError] = useState('')
  const [errorLink, setErrorLink] = useState('')
  const [signUpInfo, setSignUpInfo] = useState({
    email: '',
    password: '',
    confirmPassword: '',
    icsUrl: '',
    preferences: '',
  })

  const { email, password } = signUpInfo;

  function handleChange(e: any) {
    setSignUpInfo((prevState) => ({
        ...prevState,
        [e.target.name]: e.target.value
    }))
  }

  async function handleClick(e: any) {
    e.preventDefault()
    const { email, password, confirmPassword, icsUrl, preferences } = signUpInfo;
    if (password !== confirmPassword) {
        setError("Passwords do not match")
        return
    }
    console.log('passwords matched')
    const userData = {
      email, 
      password,
      icsUrl,
      preferences,
    }
    // Construct the fetch request
    const request = new Request(`../../api/users`, {
      method: "POST",
      body: JSON.stringify(userData)
    });
    // Make the fetch call and handle the response
    const response = await fetch(request);
    try { // error (has JSON response)
      const data = await response.json();
      setError(data.message)
      if (data.link) setErrorLink(data.link)
    } catch { // successful account sign up
      // convert icf link to icf via fetch
      // await ical.async.fromURL(icsUrl, function(err: any, data: any) { console.log(data); });


      // redirect to upload calendar
      window.location.href = "../../uploadcalendar"
    }
  }

  return (
    <section className='text-center'>
    <h1 className="my-7 text-7xl font-lato">Sign Up</h1>
      <form className='w-full justify-center content-centers flex flex-col'>
        <div>
          <input className='p-5 bg-blue-100 w-[50%] h-[5vh] my-3 border' name="email" type='email' placeholder="Email" value={email} onChange={handleChange} />
        </div>
        <div>
          <input className='p-5 bg-blue-100 w-[50%] h-[5vh] my-3 border' name="password" type="password" placeholder="Password" value={password} onChange={handleChange} />
        </div>
        <div>
          <input className='p-5 bg-blue-100 w-[50%] h-[5vh] my-3 border' name="confirmPassword" type="password" placeholder="Confirm Password" onChange={handleChange} />
        </div>
        <div>
          <input className='p-5 bg-blue-100 w-[50%] h-[5vh] my-3 border' name="icsUrl" type="text" placeholder="Link to ICS file" onChange={handleChange} />
        </div>
        <div>
          <input className='p-5 bg-blue-100 w-[50%] h-[5vh] my-3 border' name="preferences" type="text" placeholder="What type of events do you enjoy? ('Clubbing, sports, dancing, etc')" onChange={handleChange} />
        </div>
        <div>
          <button className='p-5 bg-blue-100 w-[50%] my-3 border rounded-xl' onClick={handleClick}>Sign Up</button>
          {error && (errorLink ? <div><Link href={errorLink} className='underline'>{error}. Click here to Log In</Link></div>: <p className='text-red-500'>{error}</p>)} 
        </div>
      </form>
    </section>
  )
}

export default Page
```

### app/uploadcalendar/page.tsx

```typescript
'use client'
import React, { ChangeEvent, useState } from 'react';

//Integrate email in this page!!!!!

const FileUpload: React.FC = () => {
  const [fileContent, setFileContent] = useState<string>(''); // State to store file content
  const [jsonData, setJsonData] = useState<any>(null); // State to store parsed JSON data

  const usernameCookie = document.cookie.match('(^|;)\\s?username\\s?=\\s?([^;]+)');
  const username = usernameCookie ? usernameCookie[2] : null;

  function parseDateString(dateString: string): Date {
    const year: number = parseInt(dateString.substr(0, 4), 10);
    const month: number = parseInt(dateString.substr(4, 2), 10) - 1; // Month in JavaScript Date object is 0-indexed
    const day: number = parseInt(dateString.substr(6, 2), 10);
    const hours: number = parseInt(dateString.substr(9, 2), 10);
    const minutes: number = parseInt(dateString.substr(11, 2), 10);
    const seconds: number = parseInt(dateString.substr(13, 2), 10);
  
    return new Date(Date.UTC(year, month, day, hours, minutes, seconds));
  }
  

  const handleFileUpload = (event: ChangeEvent<HTMLInputElement>) => {
    if (!event.target.files || event.target.files.length === 0) {
      return;
    }

    const file = event.target.files[0];
    const reader = new FileReader();

    reader.onload = () => {
      const fileContentString = reader.result as string;
      setFileContent(fileContentString); // Set file content in state
      // console.log(fileContentString);
      const lines = fileContentString.split('\n');
      // console.log(lines);
      const filteredArray = lines.filter(line=>{
        return line.includes("DTSTART") || line.includes("DTEND") || line.includes("SUMMARY");
      });
      //  for (let i = 0; i < filteredArray.length; i++){
      //   console.log(filteredArray[i]);
      // }
      // const newArray = filteredArray.splice(2);
      const newArray = filteredArray;
      let index = 0;
      const events: any[] = [];
      const pattern = /\b\d{8}T\d{6}Z\b/;
      // for (let i = 0; i < newArray.length; i++){
      //   console.log(newArray[i]);
      // }
      // console.log(newArray.length)
      while (index < newArray.length){
        const start_time_regex = newArray[index].match(pattern);
        let start_time;
        if (start_time_regex){
          start_time = parseDateString(start_time_regex.join(''))
        }
        index++;

        let end_time;
        // console.log(newArray[index]);
        const end_time_regex = newArray[index].match(pattern);
        if (end_time_regex){
          end_time = parseDateString(end_time_regex.join(''))
        }

        index++;
        const event_name = newArray[index].substring(8, newArray[index].length - 1);
        index++;
        const email = username
        const event = {
          email,
          start_time,
          end_time,
          event_name
        };

        if (start_time){
          const month = start_time.getMonth();
          const year =  start_time.getFullYear();
          if (year >= 2024 || (year === 2023 && month >= 9)){
            events.push(event);
          }
        }
        
      }
      // console.log("Events")
      // console.log(events);
      // const eventsJSON = JSON.stringify(events);
      // console.log("EventsJSON")
      console.log("Before request");   
      for (let i = 0; i < events.length; i++){
        // console.log(events[i]);
        const eventJSON = JSON.stringify(events[i]);
        const request = new Request(`../api/calendar`, {
          method: "Post",
          body: eventJSON,
        });
        fetch(request)
      }   
      

    };

    // Read the file as text
    reader.readAsText(file);

    setTimeout(() => {window.location.href = '../../'}, 1000);
  };

  return (
    <div className='flex rounded-xl align-middle justify-center m-[10%] p-10 bg-blue-200 flex-col flex-grow'>
      <h1>Upload File and Convert to JSON</h1>
      <input type="file" onChange={handleFileUpload} />
      <div>
      </div>
    </div>
  );
};

export default FileUpload;

```

### app/plan/page.tsx

```typescript
'use client'
import React from 'react';
const axios = require('axios')

//Integrate own email
//Need to

const Plan: React.FC = () => {

    const handleClick = (e) => {
        e.preventDefault;
        union("johnsmith@gmail.com", "kellysmith@gmail.com");
        

    }
  
    async function union(myEmail: string, friendEmail: string) {
        
        const myRequest = new Request(`../api/plan`, {
            method: "GET",
            headers: {
                email: myEmail,
            },
          });
          
        const mySchedule = await fetch(myRequest).then(response => {
            if (!response.ok) {
            throw new Error("Network response was not ok");
            }
            return response.json(); 
        })
        // console.log("MySchedule")
        // console.log(mySchedule)

        const friendRequest = new Request(`../api/plan`, {
            method: "GET",
            headers: {
                email: friendEmail,
            },
          });
          
          const friendSchedule = await fetch(friendRequest).then(response => {
            if (!response.ok) {
            throw new Error("Network response was not ok");
            }
            return response.json(); 
        })
        
        const myArray: [any, any][] = []
        // mySchedule.map(mySchedule => [mySchedule.start_time, mySchedule.end_time])
        for (let i = 0; i < mySchedule.length; i++){
            const temp: [any, any] = [new Date(mySchedule[i].start_time).getTime(), new Date(mySchedule[i].end_time).getTime()]
            myArray.push(temp)
            // if (myArray[i][1]) {
            //     myArray.pop();
            // }
        }

        for (let i = 0; i < mySchedule.length; i++){
            
        }
        // console.log(myArray)

        const friendArray: [any, any][] = []
        for (let i = 0; i < friendSchedule.length; i++){
            const temp: [any, any] = [new Date(friendSchedule[i].start_time).getTime(), new Date(friendSchedule[i].end_time).getTime()]
            friendArray.push(temp)
            // if (isNaN(friendArray[i][1])){
            //     friendArray.pop();
            // }
        }
        // console.log(friendArray);



        // const friendArray = friendSchedule.map(friendSchedule => [friendSchedule.start_time, friendSchedule.end_time])
        // Merge the meetings
        // const myArray: [Date, Date][] = [];
        // for (let i = 0; i < mySchedule.length; i++){
        //     const startTime = new Date(mySchedule[i].start_time)
        //     const endTime = new Date(mySchedule[i].end_time)
        //     console.log(endTime);
        //     const temp: [Date, Date] = [startTime, endTime]
        //     console.log(temp)
        //     myArray.push(temp)
        // }

        // const myArray = mySchedule.map(mySchedule =>[new Date(mySchedule.start_time), new Date(mySchedule.end_time)]);
        
        // const friendArray = friendSchedule.map(friendSchedule =>[new Date(friendSchedule.start_time), new Date(friendSchedule.end_time)]);
    
        const sorted = myArray.concat(friendArray);
        // console.log(sorted);

        

        sorted.sort((a: any, b: any) => {
            return a[0] > b[0] ? 1 : -1;
        });


        // have actual overlaps
        const merged: [any, any][] = [sorted[0]];

        for (let i = 1; i < sorted.length; i++){
            let currentMeeting = sorted[i];
            let lastMergedMeeting = merged[merged.length - 1];
            if (currentMeeting[0] <= lastMergedMeeting[1]){
                lastMergedMeeting[1] = Math.max(lastMergedMeeting[1], currentMeeting[1]);
            } else {
                // console.log(currentMeeting);
                merged.push(currentMeeting);
            }
        }

        // console.log(merged);

        // need prev end 
        // Find the gaps
        const openSlots: [any, any][] = [];
        let prevEndTime = -1;
        for (const interval of merged){
            if (prevEndTime !== -1 && prevEndTime < interval[0]){
                const temp: [any, any] = [prevEndTime, interval[0]];
                const intervalHour = (new Date(interval[0])).getHours()
                const intervalDay = (new Date(interval[0])).getDate()

                const prevEndTimeHour = (new Date(prevEndTime)).getHours()
                const prevEndTimeDay = (new Date(prevEndTime)).getDate()
                if (prevEndTimeHour >=6 && prevEndTimeHour <= 23 && intervalHour >= 6 && intervalHour <= 23 && prevEndTimeDay == intervalDay){
                    const temp: [any, any] = [prevEndTime, interval[0]]
                    openSlots.push(temp);
                }
            }
            prevEndTime = Math.max(interval[1], prevEndTime);
        }
        for (let i = 0; i < openSlots.length; i++){
            const diff = openSlots[i][1] - openSlots[i][0];
            openSlots[i].push(diff);
        }
        // console.log(openSlots)

        openSlots.sort((a: any, b: any) => {
            return a[2] < b[2] ? 1 : -1;
        });

        // console.log(openSlots)
        console.log(new Date(openSlots[0][0]))
        console.log(new Date(openSlots[0][1]))
        callAI(new Date(openSlots[0][0]), new Date(openSlots[0][1]) )
    }

    async function callAI(s: Date, e: Date){
        let start = s.toString().substring(0, 11) + s.toString().substring(16, 21);
        let end = e.toString().substring(0, 11) + e.toString().substring(16, 21);
        


        let input = "My friend and I are free from " + start + " to " + end + ". My preferences are " + "football,hiking,grilling,dining,poetry" + " and my friend's preferences are" + "basketball,nature,tacos,concerts,sculpting" + "Plan an activity for us and return your output in a json format\nexample:\n{\n    title:\n    description:\n}";

        
        // const res = axios.post('https://api.together.xyz/inference', {
        // "model": "OpenAssistant/llama2-70b-oasst-sft-v10",
        // "max_to
[truncated — 2345 more characters]
```

### app/api/preferences/route.js

```javascript
'use server'
 
import { cookies } from 'next/headers'
import prisma from '../../libs/prisma';
import { NextResponse } from 'next/server';
 
// GET request to log a registered user in
export const GET = async (req) => {
    try {
        const email = req.headers.get("email");
        const user = await prisma.user.findUnique({
            where: {
                email: email,
              },
        })
        if (user === null) {
            return NextResponse.json({message: "User does not exist...", link: "../../signup"})
        }

        return NextResponse.json({message: user.preferences});
    } catch(err) {
        return NextResponse.json({message: "GET ERROR", err});
    }
}

```

### app/api/plan/route.js

```javascript
import prisma from '../../libs/prisma';
import { NextResponse } from 'next/server';

export const GET = async (req) => {
    try {
        const email = req.headers.get("email");
        const schedules = await prisma.event.findMany({
            where: {
                email: email,
              },
              select: {
                start_time: true,
                end_time: true
              },
        });
        const scheduleTimes = schedules.map((schedule) => ({
            start_time: schedule.start_time, // Convert to ISO String if necessary
            end_time: schedule.end_time,     // Convert to ISO String if necessary
          }));
          console.log(scheduleTimes)
        return NextResponse.json(scheduleTimes);
    } catch(err) {
        return NextResponse.json({message: "GET ERROR", err})
    }

}
```

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