Skip to content

Commit

Permalink
feat(turborepo): fix PR #49 (#82)
Browse files Browse the repository at this point in the history
* build: move all nextjs code to www directory

* Migrate config files over to www

* Setup turbo

* Update docs

* Merge branch 'main' into feat-monorepo

* Delete duplicate actions

* Merge branch 'main' of github.com:alexghirelli/projectx into feat-monorepo

* chore: update paths

* chore: update paths

---------

Co-authored-by: Connor Littleton <[email protected]>
  • Loading branch information
alexghirelli and Connor Littleton authored Jan 25, 2024
1 parent 4659cbd commit 7e82cbf
Show file tree
Hide file tree
Showing 349 changed files with 13,673 additions and 2,102 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ next-env.d.ts
.vscode
.contentlayer

venv
venv

# Turbo
.turbo
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,55 @@

## Introduction

Lets goooo - Next.js 14, Prisma, Planetscale, Auth.js, Resend, React Email, Shadcn/ui, and Stripe.
Lets goooo - Next.js 14, Turborepo, Prisma, Planetscale, Auth.js, Resend, React Email, Shadcn/ui, and Stripe.
<br/>
All seamlessly integrated with the Projectx to accelerate the development.

## Directory Structure

ProjectX is a monorepo managed by [Turborepo](https://turbo.fish/). The monorepo is split between `apps` and `packages` directories.

- **Apps** are the Next.js apps that are deployed to Vercel (this is where most development is done).
- **Packages** are the shared packages that are used by the apps (e.g. `@projectx/components`)

````
## Installation
Clone & create this repo locally with the following command:
```bash
git clone https://github.com/meglerhagen/projectx.git
```
````

1. Install dependencies using pnpm:
1. Install dependencies using yarn:

```sh
yarn install
```

2. Copy `.env.example` to `.env` and update the variables.
2. Move into the app directory (this is where the next.js app lives):

```sh
cd apps/www
```

3. Copy `.env.example` to `.env.local` and update the variables.

```sh
cp .env.example .env.local
```

3. Input everything you need for the env.
4. Input everything you need for the env.

4. Start the development server:
5. Start the development server from either yarn or turbo:

```sh
# At the root of the mono repo
yarn dev

# Or from the app directory
cd apps/www
yarn dev
```

Expand Down
54 changes: 0 additions & 54 deletions app/api/ai/generateDescription/route.ts

This file was deleted.

File renamed without changes.
File renamed without changes.
45 changes: 45 additions & 0 deletions apps/www/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# email
/.react-email/

.vscode
.contentlayer

venv
3 changes: 3 additions & 0 deletions apps/www/.prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
...require("../../prettier.config.js"),
};
37 changes: 37 additions & 0 deletions apps/www/actions/account-switcher/get-workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// actions/get-user-workspaces.js
"use server";

import { prisma } from "@/lib/db";
import { getCurrentUser } from "@/lib/session";

export async function getUserWorkspaces() {
const user = await getCurrentUser();
const userId = user?.id;

// console.log(`Request received to get workspaces for User ID: ${userId}`);

try {
const workspaceData = await prisma.workspace.findMany({
where: { userId },
select: {
id: true,
name: true,
// Include other fields as needed
},
});

// Transform the workspace data
const transformedWorkspaces = workspaceData.map((ws) => ({
workspaceName: ws.name,
email: user?.name,
icon: "vercel",
name: user?.name,
}));

// console.log(`Workspaces retrieved successfully for user ID: ${userId}`);
return { success: true, workspaces: transformedWorkspaces };
} catch (error) {
console.error(`Error retrieving workspaces for user ID: ${userId}`, error);
return { success: false, error: error.message };
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ async function sendOnboardingEmail(email: string, name: string) {
}
}

export default sendOnboardingEmail;
export default sendOnboardingEmail;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getCurrentUser } from "@/lib/session";
import { isValidJSONString } from "@/lib/utils";
import { CategoriesDashboard } from "@/components/categories/components/categories-dashboard";
import { accounts, mails } from "@/components/investments/data";
import { RecurringDashboard } from "@/components/recurring/components/recurring-dashboard";
import { RecurringDashboard } from "@/components/transactions/components/recurring-dashboard";

export const metadata = {
title: "Transactions",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
47 changes: 47 additions & 0 deletions apps/www/app/api/ai/generateDescription/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// app/api/ai/generateDescription/route.ts
import { NextRequest, NextResponse } from "next/server";
import axios from "axios";

export async function POST(request: NextRequest) {
const requestBody = await request.json();
const { allResponses, text } = requestBody;

// Construct messages for the chat completion request
const messages = allResponses.map(response => {
return {
role: "user",
content: `Options: ${response.options.join(", ")}.`
};
});

console.log(messages);

// Add the specific request text
messages.push({ role: "system", content: "I need you to act like a real estate agent and write a description for this house. I need a title and a description" });
messages.push({ role: "user", content: text });

try {
const openaiResponse = await axios.post(
"https://api.openai.com/v1/chat/completions",
{
model: "gpt-4",
messages: messages
},
{
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
}
}
);

// Extracting the assistant's response
const completion = openaiResponse.data.choices[0].message.content;

// Send the assistant's response back to the client
return NextResponse.json({ description: completion });
} catch (error) {
console.error("Error in generating description:", error);
return NextResponse.json({ error: "Failed to generate description" }, { status: 500 });
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
32 changes: 32 additions & 0 deletions apps/www/components/buttons/AddFilesButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { UploadDropZone } from "../fileupload/UploadDropZone"

export function AddFilesButton({propertyId, slug}) {

return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Upload</Button>
</DialogTrigger>
<DialogContent className="md:w-fit grid justify-center max-h-[100%] max-sm:px-0">
<DialogHeader>
<DialogTitle>Upload your files</DialogTitle>
<DialogDescription>
Upload all your photos for your property
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<UploadDropZone slug={slug} propertyId={propertyId} />
</div>
</DialogContent>
</Dialog>
)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ export function AccountSwitcher({
</SelectContent>
</Select>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { TransactionsReviewTable } from "@/components/new-dashboard/components/t

import { Mail } from "../data";
import { AccountsReviewTable } from "./accounts-review-table";
import { PositionsTable } from "./positions-table";
import { PositionsTable } from "@/components/transactions/components/positions-table";

interface MailDisplayProps {
mail: Mail | null;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions apps/www/components/properties/PropertyImageWithOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// components/properties/PropertyImageWithOptions.js
import PropertyPicture from './PropertyPicture';
import { SelectInputForm } from '../forms/select-input-form';

const PropertyImageWithOptions = ({ image }) => {
console.log(image)
// Transform the image options into the correct format for SelectInputForm
const options = [
{ key: 'option1', label: 'Option 1', description: image.option1, imageId: image.id, selectedOption: image.selectedOption },
{ key: 'option2', label: 'Option 2', description: image.option2, imageId: image.id, selectedOption: image.selectedOption },
{ key: 'option3', label: 'Option 3', description: image.option3, imageId: image.id, selectedOption: image.selectedOption },
].filter(option => option.description); // Filter out options without a description

return (
<div className="lg:flex min-lg:flex-col justify-center max-lg:space-y-4 gap-x-4">
<div className="lg:w-1/2">
<PropertyPicture src={image.url} alt={image.description} />
</div>
<div className="lg:w-1/2">
<SelectInputForm image={image} options={options} />
</div>
</div>
);
};

export default PropertyImageWithOptions;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 7e82cbf

Please sign in to comment.