# Project export: Rentora

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: CruzHacks 2024
- Tagline: Rentora is a website dedicated to simplifying the process of renting homes for students. We help users to build a rental application, and use AI to match students with properties that fit their needs.
- Devpost: https://devpost.com/software/rentora
- GitHub: https://github.com/vinayakvadoothker/CruzHacks2024
- Video: https://www.youtube.com/embed/1P2J9cvk3WM?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — vinayakvadoothker (20 commits)

## Devpost submission (written by the team)

### Overview

"Rent Now"

### Inspiration

The inspiration behind Rentora stems from the challenges we faced when searching for off-campus housing ourselves. We recognized the need for a platform that simplifies the entire rental process, from application to property selection.

### What it does

Rentora is a comprehensive platform designed to streamline the off-campus rental experience for students. It helps users in creating compelling rental applications, leverages AI for property matching, and offers rental-related information.

### How we built it

Python: Used for backend tasks, including server-side logic, data processing, and integration with AI algorithms. JavaScript (JS): Employed for frontend development to create an interactive and dynamic user interface. CSS: Utilized for styling and formatting the website to ensure an appealing and user-friendly design. OpenAI: Integrated to implement advanced AI capabilities, such as natural language processing and recommendation systems. Google Cloud Firebase: Used for backend services, including database management, user authentication, and data storage. Google Maps API: Integrated for location-based services and property mapping features, enhancing the user experience. Flask: Employed as a Python web framework to build the backend server, handle HTTP requests, and serve API endpoints. NodeMailer: Used for sending email notifications and communications to users, enhancing the platform's functionality.

### Challenges we ran into

During the development process, we faced challenges in optimizing the AI algorithms for accurate property matches. We also ran into challenges when trying to properly build the rental application.

### Accomplishments we're proud of

We're proud of our AI-driven property matching and the easy rental application builder.

### What we learned

We learned the significance of leveraging technology to solve problems that affect us and our peers. We also learned to develop in Python and connect it to a React website.

### What's next

In the future, Rentora aims to expand its services to cover a wider range of universities and offer additional features, such as integrated payment solutions and enhanced property management tools.

## README (from the GitHub repository)

# Rentora
A Repo for A Website and App - Rentora.net


# Rentora Website

This is the repository for the Rentora website built with React.

## Getting Started

### Prerequisites

Before you start, make sure you have Node.js and npm installed on your machine.

### Installation

1. Clone the repository:

```bash
git clone https://github.com/vinayakvadoothker/rentora_repo
```

2. Navigate to the project directory:

```bash
cd rentora-website
```

3. Install dependencies:

```bash
npm install
```

### Configuration

1. Create a .env file in the root of your project.

2. Add your Clerk Publishable key, Google Maps API key, and OpenAI API key to the .env file:

```env
REACT_APP_CLERK_PUBLISHABLE_KEY=your-publishable-key
REACT_APP_GOOGLE_MAPS_API_KEY=your-publishable-key
OPENAI_API_KEY=your-publishable-key
```

### Usage

#### Development

To run the project in development mode:

```bash
npm run dev
```

This will start the development server at [http://localhost:3000](http://localhost:3000).

#### Production Build

To create a production-ready build:

```bash
npm run build
```
USE THIS TO USE WITH LOGIN CREDS (Clerk)

This command generates a build folder with optimized and minified files. You can deploy the contents of this folder to a web server.

### Folder Structure

The project structure is organized as follows:

- public: Contains the public assets and the main index.html.
- src: Contains the source code for the React app.
  - components: React components used in the app.
  - App.js: The main component that renders the entire app.
  - index.js: Entry point for React rendering.
  - Other necessary files like index.css, App.css, etc.

### Additional Information

- The website uses [Clerk](https://docs.clerk.dev/) for authentication. Make sure to configure Clerk accordingly.

## License

This project is under Vinayak Vadoothker's Purview


## Detected evidence (automated analysis)

Indexed codebase: 92 recognized source files, 472 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- Firebase (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Flask (technology) — claimed on Devpost, not found in the code
- Python (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (114 of 114)

```
.DS_Store
.github/workflows/main.yml
package.json
README.md
rentora-website/.gcloudignore
rentora-website/.gitignore
rentora-website/app.yaml
rentora-website/applyToListing.js
rentora-website/cors.json
rentora-website/emailServer.js
rentora-website/individualpdf.js
rentora-website/netlify.toml
rentora-website/package.json
rentora-website/pdfFieldNamesGenerator.js
rentora-website/public/index.html
rentora-website/public/manifest.json
rentora-website/public/robots.txt
rentora-website/README.md
rentora-website/rentora-ai-assistant.js
rentora-website/rentora-dbfa3-firebase-adminsdk-4rpix-4bb6bae0fe.json
rentora-website/rentora-servers/.eslintrc.json
rentora-website/rentora-servers/.gitignore
rentora-website/rentora-servers/app/globals.css
rentora-website/rentora-servers/app/layout.tsx
rentora-website/rentora-servers/app/page.tsx
rentora-website/rentora-servers/next.config.mjs
rentora-website/rentora-servers/package.json
rentora-website/rentora-servers/pages/api/combine-roommate-applications.js
rentora-website/rentora-servers/pages/api/fetch_user_details.js
rentora-website/rentora-servers/pages/api/firebase_admin.js
rentora-website/rentora-servers/pages/api/generate-pdf/[userId].js
rentora-website/rentora-servers/pages/api/payment-transfers.js
rentora-website/rentora-servers/pages/api/rentora-dbfa3-firebase-adminsdk-4rpix-4bb6bae0fe.json
rentora-website/rentora-servers/pages/api/rentora1.json
rentora-website/rentora-servers/pages/api/send_email.js
rentora-website/rentora-servers/postcss.config.js
rentora-website/rentora-servers/README.md
rentora-website/rentora-servers/tailwind.config.ts
rentora-website/rentora-servers/tsconfig.json
rentora-website/rentora1.json
rentora-website/src/.DS_Store
rentora-website/src/App.css
rentora-website/src/App.js
rentora-website/src/App.test.js
rentora-website/src/ChatBot.css
rentora-website/src/ChatBot.js
rentora-website/src/components/.DS_Store
rentora-website/src/components/AboutPage.js
rentora-website/src/components/BuyPage.js
rentora-website/src/components/config.js
rentora-website/src/components/Dashboard.css
rentora-website/src/components/Dashboard.js
rentora-website/src/components/OnboardingPage.css
rentora-website/src/components/OnboardingPage.js
rentora-website/src/components/ProfilePage.css
rentora-website/src/components/ProfilePage.js
rentora-website/src/components/PublicProfilePage.css
rentora-website/src/components/PublicProfilePage.js
rentora-website/src/components/Rent Pages/.DS_Store
rentora-website/src/components/Rent Pages/ForAllPage.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/AddListingPermissions.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/AddOffCampusListing.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/ApplyPopup_Custom.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/ApplyPopup.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/ApplyPopup.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/GuarantorForm.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/GuarantorForm.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/listings.txt
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusApplications.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusApplications.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingDashboard.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep1.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep10.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep11.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep12.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep13.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep14.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep15.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep16.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep17.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep18.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep19.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep2.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep20.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep21.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep22.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep23.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep3.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep4.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep5.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep6.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep7.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep8.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/OffCampusHousingFormStep9.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/ProgressBar.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/ProgressBar.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/Spinner.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/Spinner.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/StepContext.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/Stepper.css
rentora-website/src/components/Rent Pages/OffCampusFormSteps/Stepper.js
rentora-website/src/components/Rent Pages/OffCampusFormSteps/styles.css
rentora-website/src/components/Rent Pages/OffCampusPage.js
rentora-website/src/components/RentPage.js
rentora-website/src/components/ResidencyPaymentTransfer.js
rentora-website/src/components/SignIn.js
rentora-website/src/components/SignUp.js
rentora-website/src/components/VenturePage.js
rentora-website/src/config.js
rentora-website/src/index.css
rentora-website/src/index.js
rentora-website/src/reportWebVitals.js
rentora-website/src/setupTests.js
rentora-website/user-details.js
```

### Dependencies

- package.json: firebase-admin@^12.0.0, pdf-lib@^1.17.1, qrcode@^1.5.3
- rentora-website/package.json: @clerk/clerk-react@^4.28.1, @emotion/react@^11.11.1, @emotion/styled@^11.11.0, @mui/material@^5.14.18, @testing-library/jest-dom@^5.17.0, @testing-library/react@^13.4.0, @testing-library/user-event@^13.5.0, @types/react@^18.2.39, axios@^1.6.5, body-parser@^1.20.2, braintree@^3.23.0, browserify-zlib@^0.2.0, buffer@^6.0.3, concurrently@^8.2.2, cors@^2.8.5, crypto@^1.0.1, crypto-browserify@^3.12.0, crypto-js@^3.1.9-1, crypto-lite@^21.8.0, dotenv@^16.3.1, express@^4.18.2, firebase@^10.7.0, firebase-admin@^12.0.0, google-auth-library@^9.4.1, googleapis@^129.0.0, https-browserify@^1.0.0, jwt-decode@^4.0.0, next@^14.0.4, nextjs-cors@^2.2.0, node-fetch@^3.3.2, nodemailer@^6.9.7, openai@^4.24.7, os@^0.1.2, os-browserify@^0.3.0, path@^0.12.7, path-browserify@^1.0.1, pdf-lib@^1.17.1, pdfjs-dist@^3.4.120, qrcode@^1.5.3, qrcode.react@^3.1.0, react@^18.2.0, react-chat-widget@^3.1.4, react-datepicker@^4.25.0, react-dom@^18.2.0, react-frame-component@^5.2.6, react-pdf@^7.7.0, react-places-autocomplete@^7.3.0, react-router-dom@^6.20.0, react-scripts@^5.0.1, stream@0.0.2, stream-browserify@^3.0.0, stream-http@^3.2.0, typescript@^5.3.3, url@^0.11.3, web-vitals@^2.1.4
- rentora-website/rentora-servers/package.json: @types/node@^20, @types/react@^18, @types/react-dom@^18, autoprefixer@^10.0.1, body-parser@^1.20.2, braintree@^3.23.0, cors@^2.8.5, eslint@^8, eslint-config-next@14.1.0, eslint-config-react-app@^7.0.1, express@^4.18.2, firebase-admin@^12.0.0, next@14.1.0, next-cors@^1.0.0, nextjs-cors@^2.2.0, nodemailer@^6.9.10, pdf-lib@^1.17.1, postcss@^8, qrcode@^1.5.3, react@^18, react-dom@^18, tailwindcss@^3.3.0, typescript@^5

### Recent commits (newest first)

- Temp update payment transfers (#9)
- updates
- updates
- updates
- updates
- up
- Update README.md (#5)
- Update README.md
- added routes (#4)
- added routes
- update
- name
- combine
- update to step 20
- update to guarantor form workflow
- Update individualpdf.js
- Update [userId].js
- update
- updates
- updates

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

### package.json

```
{
  "dependencies": {
    "firebase-admin": "^12.0.0",
    "pdf-lib": "^1.17.1",
    "qrcode": "^1.5.3"
  }
}

```

### rentora-website/package.json

```
{
  "name": "rentora-website",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@clerk/clerk-react": "^4.28.1",
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@mui/material": "^5.14.18",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/react": "^18.2.39",
    "axios": "^1.6.5",
    "body-parser": "^1.20.2",
    "braintree": "^3.23.0",
    "browserify-zlib": "^0.2.0",
    "buffer": "^6.0.3",
    "cors": "^2.8.5",
    "crypto": "^1.0.1",
    "crypto-browserify": "^3.12.0",
    "crypto-js": "^3.1.9-1",
    "crypto-lite": "^21.8.0",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "firebase": "^10.7.0",
    "firebase-admin": "^12.0.0",
    "google-auth-library": "^9.4.1",
    "googleapis": "^129.0.0",
    "https-browserify": "^1.0.0",
    "jwt-decode": "^4.0.0",
    "next": "^14.0.4",
    "nextjs-cors": "^2.2.0",
    "node-fetch": "^3.3.2",
    "nodemailer": "^6.9.7",
    "openai": "^4.24.7",
    "os": "^0.1.2",
    "os-browserify": "^0.3.0",
    "path": "^0.12.7",
    "path-browserify": "^1.0.1",
    "pdf-lib": "^1.17.1",
    "pdfjs-dist": "^3.4.120",
    "qrcode": "^1.5.3",
    "qrcode.react": "^3.1.0",
    "react": "^18.2.0",
    "react-chat-widget": "^3.1.4",
    "react-datepicker": "^4.25.0",
    "react-dom": "^18.2.0",
    "react-frame-component": "^5.2.6",
    "react-pdf": "^7.7.0",
    "react-places-autocomplete": "^7.3.0",
    "react-router-dom": "^6.20.0",
    "react-scripts": "^5.0.1",
    "stream": "0.0.2",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "url": "^0.11.3",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "dev:api": "node emailServer.js",
    "dev:openai": "node rentora-ai-assistant.js",
    "dev:pdf-individual": "node individualpdf.js",
    "dev:apply-to-listing": "node applyToListing.js",
    "dev:fetch-user-details": "node user-details.js",
    "dev:client": "npm start",
    "dev:server": "/usr/local/bin/python3 /Users/vinv/Documents/Rentora.ai/rentora-website/app.py",
    "build:rentora-servers": "cd rentora-servers && npm run build",
    "start:rentora-servers": "cd rentora-servers && npm start",
    "dev": "concurrently \"npm run dev:client\" \"npm run dev:server\" \"npm run dev:api\" \"npm run dev:openai\" \"npm run dev:pdf-individual\" \"npm run dev:apply-to-listing\" \"npm run dev:fetch-user-details\" \"npm run build:rentora-servers\" \"npm run start:rentora-servers\""
  },
  "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": {
    "concurrently": "^8.2.2",
    "typescript": "^5.3.3"
  }
}

```

### rentora-website/rentora-servers/package.json

```
{
  "name": "rentora-servers",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "body-parser": "^1.20.2",
    "braintree": "^3.23.0",
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "firebase-admin": "^12.0.0",
    "next": "14.1.0",
    "next-cors": "^1.0.0",
    "nextjs-cors": "^2.2.0",
    "nodemailer": "^6.9.10",
    "pdf-lib": "^1.17.1",
    "qrcode": "^1.5.3",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "eslint-config-react-app": "^7.0.1",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  }
}

```

### rentora-website/src/index.js

```javascript
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';

const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
const googleMapsApiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
const email = process.env.REACT_APP_EMAIL;
const password = process.env.REACT_APP_PASSWORD;
const openaikey = process.env.OPENAI_API_KEY;


// Load Google Maps API script
const googleMapsScript = document.createElement('script');
googleMapsScript.src = `https://maps.googleapis.com/maps/api/js?key=${googleMapsApiKey}&libraries=places`;
googleMapsScript.async = true;
googleMapsScript.defer = true;
document.head.appendChild(googleMapsScript);

// Use createRoot instead of ReactDOM.render
const root = document.getElementById('root');
const createRoot = ReactDOM.createRoot(root);

// Wrap your app component in createRoot().render()
createRoot.render(
  <React.StrictMode>
    <Router>
      <App openaikey={openaikey} clerkPubKey={clerkPubKey} googleMapsApiKey={googleMapsApiKey} email={email} password={password} />
    </Router>
  </React.StrictMode>
);

```

### rentora-website/src/App.js

```javascript
// Import the necessary components and functions
import React from 'react';
import { ClerkProvider, SignedIn, SignedOut, useClerk } from '@clerk/clerk-react';
import { BrowserRouter as Router, Route, Routes, Navigate, Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom'; // Import useNavigate hook
import ChatBot from './ChatBot'; // Import your ChatBot component
import { StepProvider } from './components/Rent Pages/OffCampusFormSteps/StepContext';
import Dashboard from './components/Dashboard'; // Import Dashboard component
import OnboardingPage from './components/OnboardingPage'; // Import OnboardingPage component
import BuyPage from './components/BuyPage'; // Import BuyPage component
import RentPage from './components/RentPage'; // Import RentPage component
import ForAllPage from './components/Rent Pages/ForAllPage';
import OffCampusPage from './components/Rent Pages/OffCampusPage';
import VenturePage from './components/VenturePage'; // Import VenturePage component
import ProfilePage from './components/ProfilePage'; // Import ProfilePage component
import GuarantorForm from './components/Rent Pages/OffCampusFormSteps/GuarantorForm'; // Import GuarantorForm component
import PublicProfilePage from './components/PublicProfilePage'; // Import GuarantorForm component

import ResidencyPaymentTransfer from './components/ResidencyPaymentTransfer';

import AddOffCampusListing from './components/Rent Pages/OffCampusFormSteps/AddOffCampusListing'; // Import AddOffCampusListing component
import OffCampusApplications from './components/Rent Pages/OffCampusFormSteps/OffCampusApplications';
import logo from './components/images/Rentora_Logo.png'
import './App.css';

// Check for missing publishable key
if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) {
  throw new Error("Missing Publishable Key");
}

// Extract environment variables
const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
const googleMapsApiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
const openaikey = process.env.OPENAI_API_KEY;

// Define Header component
const Header = () => {
  const { user, signOut } = useClerk();
  const navigate = useNavigate(); // Access navigate function

  const handleSignOut = async () => {
    try {
      await signOut();
      navigate('/onboarding'); // Redirect to '/onboarding' after successful sign-out
    } catch (error) {
      console.error('Error signing out:', error);
    }
  };

  const showDropdown = () => {
    const dropdown = document.getElementById('profileDropdown');
    if (dropdown) {
      dropdown.style.display = 'block';
    }
  };

  const hideDropdown = () => {
    const dropdown = document.getElementById('profileDropdown');
    if (dropdown) {
      dropdown.style.display = 'none';
    }
  };

  return (
    <nav>
      <ul style={{ display: 'flex', alignItems: 'center' }}>
        {/* Logo at the far left */}
        <li>
          <a href="http://www.rentora.net" rel="noopener noreferrer">
            <img src={logo} alt="Rentora Logo" className="logo-circle" />
          </a>
        </li>
        <li style={{ marginRight: 'auto' }}>
          <Link to="/rent/off-campus" style={styles.navLink}>Listings</Link>
        </li>
        <li>
          <Link to="/rent/off-campus/myapplications" style={styles.navLink}>My Applications</Link>
        </li>

        <SignedIn>
          <li style={styles.profileContainer} onMouseEnter={showDropdown} onMouseLeave={hideDropdown}>
            <Link to="/profile">
              <img src={user?.imageUrl} alt="Profile" style={styles.profileImage} />
            </Link>
            <div id="profileDropdown" style={styles.dropdownContent}>
              <div style={styles.dropdownItem} onClick={() => window.location.href = '/profile'}>
                <span style={styles.cursorPointer}>Profile</span>
              </div>
              <div style={styles.dropdownItem} onClick={handleSignOut}>
                <span style={styles.cursorPointer}>Sign Out</span>
              </div>
            </div>
          </li>
        </SignedIn>
      </ul>
    </nav>
  );
};

// Define RentHeader component
const RentHeader = () => {
  return (
    <nav style={{ backgroundColor: 'transparent', padding: '0' }}>
      <ul style={{ ...styles.list, display: 'flex', justifyContent: 'center' }}> {/* Centering items */}
        {/* Listings Link */}
        <li style={styles.navItemContainer}>
          <Link to="/rent/off-campus" style={styles.navLink}></Link>
        </li>

        {/* My Applications Link */}
        <li style={styles.navItemContainer}>
          <Link to="/rent/off-campus/myapplications" style={styles.navLink}></Link>
        </li>
      </ul>
    </nav>
  );
};

// Define Home component
const Home = () => {
  const { session } = useClerk();

  // Redirect to the dashboard if the user is signed in
  if (session && session.user) {
    return <Navigate to="/rent/off-campus" />;
  }

  return <OnboardingPage />;
};



// Define Portals component
const Portals = () => (
  <div>
    <SignedOut>
      <Header /> {/* Show a header that might have sign in/sign up options */}
    </SignedOut>
    <h1>Welcome to the Portals</h1>
    <SignedIn>
      <Routes>
        <Route path="/residency" element={<ResidencyPage />} />
        <Route path="/subleasing" element={<SubleasingPage />} />
        <Route path="/lease-transfers" element={<LeaseTransfersPage />} />
        <Route path="*" element={<Navigate to="/portals" replace />} />
        <Route path="/residency/payment-transfer" element={<ResidencyPaymentTransfer/>}/>
      </Routes>
    </SignedIn>
    <SignedOut>
      <div style={{ textAlign: 'center', marginTop: '20px' }}>
        <Link to="/sign-in">Sign In</Link> | <Link to="/sign-up">Sign Up</Link>
      </div>
    </SignedOut>
  </div>
);

// Define the individual pages for the new routes
const ResidencyPage = () => <h2>Residency Management Portal</h2>;
const SubleasingPage = () => <h2>Subleasing Portal</h2>;
co
[truncated — 3396 more characters]
```

### rentora-website/rentora-servers/app/layout.tsx

```typescript
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

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

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

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

```

### rentora-website/rentora-servers/app/page.tsx

```typescript
import Image from "next/image";

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
        <p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto  lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
          Get started by editing&nbsp;
          <code className="font-mono font-bold">app/page.tsx</code>
        </p>
        <div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
          <a
            className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
            href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            By{" "}
            <Image
              src="/vercel.svg"
              alt="Vercel Logo"
              className="dark:invert"
              width={100}
              height={24}
              priority
            />
          </a>
        </div>
      </div>

      <div className="relative flex place-items-center before:absolute before:h-[300px] before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
        <Image
          className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
          src="/next.svg"
          alt="Next.js Logo"
          width={180}
          height={37}
          priority
        />
      </div>

      <div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
        <a
          href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
          className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
          target="_blank"
          rel="noopener noreferrer"
        >
          <h2 className={`mb-3 text-2xl font-semibold`}>
            Docs{" "}
            <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
              -&gt;
            </span>
          </h2>
          <p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
            Find in-depth information about Next.js features and API.
          </p>
        </a>

        <a
          href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
          className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
          target="_blank"
          rel="noopener noreferrer"
        >
          <h2 className={`mb-3 text-2xl font-semibold`}>
            Learn{" "}
            <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
              -&gt;
            </span>
          </h2>
          <p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
            Learn about Next.js in an interactive course with&nbsp;quizzes!
          </p>
        </a>

        <a
          href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
          className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
          target="_blank"
          rel="noopener noreferrer"
        >
          <h2 className={`mb-3 text-2xl font-semibold`}>
            Templates{" "}
            <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
              -&gt;
            </span>
          </h2>
          <p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
            Explore starter templates for Next.js.
          </p>
        </a>

        <a
          href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
          className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
          target="_blank"
          rel="noopener noreferrer"
        >
          <h2 className={`mb-3 text-2xl font-semibold`}>
            Deploy{" "}
            <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
              -&gt;
            </span>
          </h2>
          <p className={`m-0 max-w-[30ch] text-sm opacity-50 text-balance`}>
            Instantly deploy your Next.js site to a shareable URL with Vercel.
          </p>
        </a>
      </div>
    </main>
  );
}

```

### rentora-website/app.yaml

```yaml
runtime: nodejs18
env: standard
instance_class: F1
automatic_scaling:
  target_cpu_utilization: 0.6
  max_instances: 1

```

### rentora-website/pdfFieldNamesGenerator.js

```javascript
const fs = require('fs');
const { PDFDocument } = require('pdf-lib');

async function listPdfFieldNames(pdfPath) {
    // Load the PDF document
    const pdfBytes = await fs.promises.readFile(pdfPath);
    const pdfDoc = await PDFDocument.load(pdfBytes);

    // Get the form from the PDF
    const form = pdfDoc.getForm();

    // Get all fields in the form
    const fields = form.getFields();

    // Map each field to its name
    const fieldNames = fields.map(field => field.getName());

    // Log or return the field names
    console.log(fieldNames);
    return fieldNames;
}

// Call the function with the path to your PDF
listPdfFieldNames('./rentora-application.pdf');

```

### rentora-website/emailServer.js

```javascript
const express = require('express');
const nodemailer = require('nodemailer');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();
const port = 3001;

app.use(bodyParser.json());
app.use(cors());

// Add Content Security Policy headers
app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy', "default-src 'self'; font-src 'self' data:; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'");
    next();
});

// Handle preflight requests
app.options('/send-email', cors());

// Define your /send-email endpoint
app.post('/send-email', async (req, res) => {
    const { to, subject, html } = req.body;

    const transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: 'admin@rentora.net',
            pass: 'lfkb ewnl itaz snqv',
        },
    });

    const mailOptions = {
        from: 'admin@rentora.net',
        to,
        subject,
        html,
    };

    try {
        await transporter.sendMail(mailOptions);
        console.log('Email sent successfully');
        res.status(200).send('Email sent successfully');
    } catch (error) {
        console.error('Error sending email:', error);
        res.status(500).send('Internal Server Error');
    }
});

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

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