Skip to content

Commit cb64725

Browse files
committed
update README
1 parent fbb0bae commit cb64725

13 files changed

Lines changed: 356 additions & 191 deletions

File tree

README.md

Lines changed: 104 additions & 148 deletions
Large diffs are not rendered by default.

app/models/essay.server.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,60 @@
11
import type { User, Essay } from "@prisma/client";
22

3+
import OpenAI from "openai";
34
import { prisma } from "~/db.server";
45

56
export type { Essay } from "@prisma/client";
67

8+
const openai = new OpenAI({
9+
apiKey: process.env.OPENAI_API_KEY, // Store API key in environment variables
10+
});
11+
712
export function getEssay({
813
id,
914
userId,
1015
}: Pick<Essay, "id"> & {
1116
userId: User["id"];
1217
}) {
1318
return prisma.essay.findFirst({
14-
select: { id: true, body: true, title: true },
19+
select: { id: true, body: true, essayPrompt: true },
1520
where: { id, userId },
1621
});
1722
}
1823

1924
export function getEssayListItems({ userId }: { userId: User["id"] }) {
2025
return prisma.essay.findMany({
2126
where: { userId },
22-
select: { id: true, title: true },
27+
select: { id: true, essayPrompt: true },
2328
orderBy: { updatedAt: "desc" },
2429
});
2530
}
2631

27-
export function createEssay({
32+
export async function createEssay({
2833
body,
29-
title,
34+
essayPrompt,
3035
userId,
31-
}: Pick<Essay, "body" | "title"> & {
36+
}: Pick<Essay, "body" | "essayPrompt"> & {
3237
userId: User["id"];
3338
}) {
39+
// Call OpenAI API to generate an essay
40+
const response = await openai.chat.completions.create({
41+
model: "gpt-3.5-turbo", // or "gpt-3.5-turbo"
42+
messages: [
43+
{ role: "system", content: "You are an AI that writes essays." },
44+
{ role: "user", content: `Prompt: "${essayPrompt}". Notes: "${body}".` },
45+
],
46+
max_tokens: 1000,
47+
});
48+
49+
const choices = response.choices; // This contains the chat responses
50+
const essay = choices[0]?.message?.content; // The content of the first choice
51+
console.log(response, choices, essay)
52+
3453
return prisma.essay.create({
3554
data: {
36-
title,
55+
essayPrompt,
3756
body,
57+
essay,
3858
user: {
3959
connect: {
4060
id: userId,

app/routes/_index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Link } from "@remix-run/react";
33

44
import { useOptionalUser } from "~/utils";
55

6-
export const meta: MetaFunction = () => [{ title: "Remix Notes" }];
6+
export const meta: MetaFunction = () => [{ title: "Scholarships Plus" }];
77

88
export default function Index() {
99
const user = useOptionalUser();

app/routes/essays.$essayId.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default function NoteDetailsPage() {
3636

3737
return (
3838
<div>
39-
<h3 className="text-2xl font-bold">{data.essay.title}</h3>
39+
<h3 className="text-2xl font-bold">{data.essay.essayPrompt}</h3>
4040
<p className="py-6">{data.essay.body}</p>
4141
<hr className="my-4" />
4242
<Form method="post">

app/routes/essays._index.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@ import { Link } from "@remix-run/react";
22

33
export default function EssaysIndexPage() {
44
return (
5-
<p>
6-
No essay selected. Select an essay on the left, or{" "}
7-
<Link to="new" className="text-blue-500 underline">
8-
create a new essay.
9-
</Link>
10-
</p>
5+
<>
6+
<p>
7+
No essay selected. Select an essay on the left, or{" "}
8+
<Link to="new" className="text-blue-500 underline">
9+
create a new essay.
10+
</Link>
11+
</p>
12+
<button class="bg-blue-500 text-white mt-6 px-4 py-2 rounded-lg shadow-lg hover:bg-blue-600">
13+
Import From Google Drive
14+
</button>
15+
</>
1116
);
1217
}

app/routes/essays.new.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,36 @@ export const action = async ({ request }: ActionFunctionArgs) => {
1010
const userId = await requireUserId(request);
1111

1212
const formData = await request.formData();
13-
const title = formData.get("title");
13+
const essayPrompt = formData.get("essayPrompt");
1414
const body = formData.get("body");
1515

16-
if (typeof title !== "string" || title.length === 0) {
16+
if (typeof essayPrompt !== "string" || essayPrompt.length === 0) {
1717
return json(
18-
{ errors: { body: null, title: "Title is required" } },
18+
{ errors: { body: null, essayPrompt: "Essay prompt is required" } },
1919
{ status: 400 },
2020
);
2121
}
2222

2323
if (typeof body !== "string" || body.length === 0) {
2424
return json(
25-
{ errors: { body: "Body is required", title: null } },
25+
{ errors: { body: "Body is required", essayPrompt: null } },
2626
{ status: 400 },
2727
);
2828
}
2929

30-
const essay = await createEssay({ body, title, userId });
30+
const essay = await createEssay({ body, essayPrompt, userId });
3131

3232
return redirect(`/essays/${essay.id}`);
3333
};
3434

3535
export default function NewNotePage() {
3636
const actionData = useActionData<typeof action>();
37-
const titleRef = useRef<HTMLInputElement>(null);
37+
const essayPromptRef = useRef<HTMLInputElement>(null);
3838
const bodyRef = useRef<HTMLTextAreaElement>(null);
3939

4040
useEffect(() => {
41-
if (actionData?.errors?.title) {
42-
titleRef.current?.focus();
41+
if (actionData?.errors?.essayPrompt) {
42+
essayPromptRef.current?.focus();
4343
} else if (actionData?.errors?.body) {
4444
bodyRef.current?.focus();
4545
}
@@ -57,20 +57,20 @@ export default function NewNotePage() {
5757
>
5858
<div>
5959
<label className="flex w-full flex-col gap-1">
60-
<span>Title: </span>
60+
<span>Essay prompt: </span>
6161
<input
62-
ref={titleRef}
63-
name="title"
62+
ref={essayPromptRef}
63+
name="essayPrompt"
6464
className="flex-1 rounded-md border-2 border-blue-500 px-3 text-lg leading-loose"
65-
aria-invalid={actionData?.errors?.title ? true : undefined}
65+
aria-invalid={actionData?.errors?.essayPrompt ? true : undefined}
6666
aria-errormessage={
67-
actionData?.errors?.title ? "title-error" : undefined
67+
actionData?.errors?.essayPrompt ? "essayPrompt-error" : undefined
6868
}
6969
/>
7070
</label>
71-
{actionData?.errors?.title ? (
72-
<div className="pt-1 text-red-700" id="title-error">
73-
{actionData.errors.title}
71+
{actionData?.errors?.essayPrompt ? (
72+
<div className="pt-1 text-red-700" id="essayPrompt-error">
73+
{actionData.errors.essayPrompt}
7474
</div>
7575
) : null}
7676
</div>

cypress/e2e/smoke.cy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe("smoke tests", () => {
2626

2727
it("should allow you to make a note", () => {
2828
const testNote = {
29-
title: faker.lorem.words(1),
29+
essayPrompt: faker.lorem.words(1),
3030
body: faker.lorem.sentences(1),
3131
};
3232
cy.login();
@@ -37,7 +37,7 @@ describe("smoke tests", () => {
3737

3838
cy.findByRole("link", { name: /\+ new note/i }).click();
3939

40-
cy.findByRole("textbox", { name: /title/i }).type(testNote.title);
40+
cy.findByRole("textbox", { name: /essayPrompt/i }).type(testNote.essayPrompt);
4141
cy.findByRole("textbox", { name: /body/i }).type(testNote.body);
4242
cy.findByRole("button", { name: /save/i }).click();
4343

0 commit comments

Comments
 (0)