Skip to content
Open

DONE #31

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"react-dom": "^18.3.1",
"react-hook-form": "^7.50.1",
"react-router-dom": "^6.22.1",
"react-schema": "^2.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
Expand Down
Binary file modified server/notes.db
Binary file not shown.
112 changes: 101 additions & 11 deletions src/components/CreateNoteForm.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,116 @@
// TODO: Import useForm, zodResolver, axios, useNavigate, useState, and noteSchema

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import axios from "axios";
import { noteSchema } from "../schema/notes";
import { useState } from "react";
import { useNavigate } from "react-router-dom";

import { Save } from "lucide-react";

const CreateNoteForm = () => {
// TODO: Setup isSubmitting state with useState
// TODO: create navigate variable and set to useNavigate()

const CreateNoteForm = () => {
const [isSubmitting, setIsSubmitting] = useState(false);

const navigate = useNavigate();

const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: zodResolver(noteSchema),
defaultValues: {
title: "",
content: "",
},
});


// TODO: Set up the form with useForm from react-hook-form and zodResolver from @hookform/resolvers/zod

const sendToTheServer = async (data) => {
// TODO: Send the data to the server
// TODO: Use axios to create a new note in the server using the endpoint http://localhost:3001/api/notes
setIsSubmitting(true);
try {
await axios.post(`http://localhost:3001/api/notes`, data);

setTimeout(() => {
navigate("/notes");
}, 500);
} catch (error) {
console.error("Failed to create note:", error);
alert("Failed to create note. Please try again.");
} finally {
setIsSubmitting(false);
}

};

return (
<>
<h1>Create Note</h1>
{/* TODO: Setup the form with TailwindCSS, create a form with the following fields: title, content, and submit button */}
</>
<form
className="bg-white p-6 rounded-lg shadow-sm max-w-2xl mx-auto"
onSubmit={handleSubmit(async (data) => {
await sendToTheServer(data);
reset();
})}
>
<h2 className="text-xl font-semibold mb-6 text-gray-800">
Create a New Note
</h2>

<div className="mb-4">
<label
htmlFor="title"
className="block text-sm font-medium text-gray-700 mb-1"
>
Title
</label>
<input
id="title"
type="text"
className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-yellow-400 ${
errors.title ? "border-red-500" : "border-gray-300"
}`}
placeholder="Note Title"
{...register("title")}
/>
{errors.title && (
<p className="mt-1 text-sm text-red-600">{errors.title.message}</p>
)}
</div>

<div className="mb-6">
<label
htmlFor="content"
className="block text-sm font-medium text-gray-700 mb-1"
>
Content
</label>
<textarea
id="content"
rows={6}
className={`w-full px-3 py-2 border rounded-md resize-none focus:outline-none focus:ring-2 focus:ring-yellow-400 ${
errors.content ? "border-red-500" : "border-gray-300"
}`}
placeholder="Write your note here..."
{...register("content")}
/>
{errors.content && (
<p className="mt-1 text-sm text-red-600">{errors.content.message}</p>
)}
</div>

<button
type="submit"
disabled={isSubmitting}
className="w-full bg-yellow-500 hover:bg-yellow-600 text-white py-2 px-4 rounded-md transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-70"
>
<Save size={18} />
<span>{isSubmitting ? "Saving..." : "Save Note"}</span>
</button>
</form>
);

};

export default CreateNoteForm;
8 changes: 8 additions & 0 deletions src/schema/notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,13 @@ export const noteSchema = z.object({
//TODO: create the title and content schema,
// Make sure the title is required and the content is required
// Make sure the title is max 50 characters and the content is max 500 characters
title: z
.string()
.min(1, { message: "Title is required" })
.max(50, { message: "Title cannot exceed 50 characters" }),
content: z
.string()
.min(1, { message: "Content is required" })
.max(500, { message: "Content cannot exceed 500 characters" }),

});