Skip to content
Open
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
86 changes: 76 additions & 10 deletions src/components/CreateNoteForm.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,90 @@
// TODO: Import useForm, zodResolver, axios, useNavigate, useState, and noteSchema


import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { noteSchema } from "../schema/notes"; // Adjust path if needed
import { Save } from "lucide-react";

const CreateNoteForm = () => {
// TODO: Setup isSubmitting state with useState
// TODO: create navigate variable and set to useNavigate()
// Setup isSubmitting state
const [isSubmitting, setIsSubmitting] = useState(false);

// ✅ Setup navigate
const navigate = useNavigate();

// TODO: Set up the form with useForm from react-hook-form and zodResolver from @hookform/resolvers/zod
// ✅ Set up useForm with zodResolver
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: zodResolver(noteSchema),
});

// ✅ Submit handler
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);
navigate("/notes");
} catch (err) {
console.error("Error creating note:", err);
alert("Failed to create note.");
} 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 */}
<h1 className="text-2xl font-bold text-center mt-8">Create Note</h1>
{/* ✅ Form with TailwindCSS */}
<form
onSubmit={handleSubmit(sendToTheServer)}
className="max-w-xl mx-auto mt-8 p-6 space-y-6 bg-white border rounded shadow"
>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Title
</label>
<input
type="text"
{...register("title")}
className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
{errors.title && (
<p className="text-red-500 text-sm mt-1">
{errors.title.message}
</p>
)}
</div>

<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Content
</label>
<textarea
{...register("content")}
rows={6}
className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
{errors.content && (
<p className="text-red-500 text-sm mt-1">
{errors.content.message}
</p>
)}
</div>

<button
type="submit"
disabled={isSubmitting}
className="w-full flex items-center justify-center gap-2 px-4 py-2 bg-yellow-400 text-white font-medium rounded-md hover:bg-yellow-500 transition disabled:opacity-50"
>
<Save size={16} />
{isSubmitting ? "Saving..." : "Save Note"}
</button>
</form>
</>
);
};
Expand Down
15 changes: 10 additions & 5 deletions src/schema/notes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { z } from "zod";

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 must be 50 characters or less" }),

content: z
.string()
.min(1, { message: "Content is required" })
.max(500, { message: "Content must be 500 characters or less" }),
});