Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

personalized daily quote section by adding different categories #194

Closed
wants to merge 5 commits into from
Closed
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
9 changes: 1 addition & 8 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@

/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/api/quote',
destination: 'https://zenquotes.io/api/random',
},
]
},

}

export default nextConfig;
Expand Down
13 changes: 13 additions & 0 deletions prisma/migrations/20241029084744_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- CreateTable
CREATE TABLE "Notes" (
"id" TEXT NOT NULL,
"content" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Notes_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Notes" ADD CONSTRAINT "Notes_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
2 changes: 2 additions & 0 deletions prisma/migrations/20241029092746_tags/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Diary" ADD COLUMN "tags" TEXT[] DEFAULT ARRAY[]::TEXT[];
2 changes: 2 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ model Diary {
content String
user User @relation(fields: [userId], references: [id])
userId String
tags String[] @default([]) // Ensure tags are stored as an array of strings
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}


model Notes {
id String @id @default(uuid())
content String
Expand Down
10 changes: 6 additions & 4 deletions src/app/api/diary/[...id]/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ export async function PATCH(req, { params }) {
}
const { id } = params;
const body = await req.json();
const { title, content } = body;
const { title, content, tags } = body; // Include tags here
try {
const user = await prisma.user.findUnique({
where: {
clerkId: userId,
}, select: {
},
select: {
id: true
}
});
Expand All @@ -51,12 +52,13 @@ export async function PATCH(req, { params }) {
},
data: {
title,
content
content,
tags: tags || [] // Update tags as well
},
});
return Response.json({ message: "diary updated successfully" });
} catch (err) {
console.log(err);
return Response.json({ error: "Error updating diary" });
}
}
}
24 changes: 16 additions & 8 deletions src/app/api/diary/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,56 @@ export async function GET(req) {
}
let user = await prisma.user.findUnique({
where: { clerkId: userId },
})
});
let diaries = await prisma.diary.findMany({
where: {
userId: user.id,
},
select: { // Optionally, select only the fields you want
id: true,
title: true,
content: true,
tags: true, // Ensure tags are selected
userId: true,
},
});

return Response.json({ diaries });
}


export async function POST(req) {
const { userId } = getAuth(req);

const body = await req.json();

if (!userId) {
return new Response(JSON.stringify({ error: "User not authenticated" }), { status: 401 });
}

try {
let clerkUser = await clerkClient.users.getUser(userId)
let clerkUser = await clerkClient.users.getUser(userId);
clerkUser = {
id: userId,
name: clerkUser.firstName + " " + clerkUser.lastName,
email: clerkUser.primaryEmailAddress.emailAddress,
}
};
let user = await prisma.user.findUnique({
where: { clerkId: clerkUser.id },
})
});
if (!user) {
user = await prisma.user.create({
data: {
clerkId: clerkUser.id,
name: clerkUser.name || '', // Use fullName if available
email: clerkUser.email || '', // Use emailAddress if available
name: clerkUser.name || '',
email: clerkUser.email || '',
},
})
});
}
const diary = await prisma.diary.create({
data: {
title: body.title,
content: body.content,
tags: body.tags || [], // Add this line to save tags
userId: user.id,
},
});
Expand Down
67 changes: 44 additions & 23 deletions src/app/daily-quote/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@ import { RiFileCopyLine } from "react-icons/ri";
export default function DailyQuote() {
const [quote, setQuote] = useState("Loading...");
const [author, setAuthor] = useState("Anonymous");
const [error, setError] = useState();
const [copied, setCopied] = useState(false);
const [category, setCategory] = useState("life"); // Default category

// Fetch quote based on category
useEffect(() => {
async function fetchData() {
try {
const response = await axios.get("/api/quote");
setQuote(response.data[0].q);
setAuthor(response.data[0].a);
} catch (error) {
setError(error);
}
}

fetchData();
}, []);
fetchQuote();
}, [category]);

const getNewQuote = async () => {
const fetchQuote = async () => {
setQuote("Loading...");
setCopied(false);
const response = await axios.get("/api/quote");
setQuote(response.data[0].q);
setAuthor(response.data[0].a);
try {
const response = await axios.get(
`https://api-get-quotes.vercel.app/api/v1/category/${category}`
);
const quotesArray = response.data.quotes; // Access the quotes array from the response

// Select a random quote from the quotes array
const randomIndex = Math.floor(Math.random() * quotesArray.length);
setQuote(quotesArray[randomIndex].quote);
setAuthor(quotesArray[randomIndex].author);
} catch (error) {
setQuote("Could not fetch quote");
setAuthor("Unknown");
}
};

const copyQuote = async () => {
Expand All @@ -49,19 +51,34 @@ export default function DailyQuote() {
</p>
</div>

{/* Category Selector */}
<div className="flex justify-center space-x-4 mb-6">
{["life", "motivation", "love", "courage", "Inspiration", "Friendship", "Hope", "Wisdom", "Nature"].map((cat) => (
<button
key={cat}
className={`px-4 py-2 rounded-md font-semibold ${
category === cat
? "bg-blue-600 text-white"
: "bg-gray-300 text-gray-800"
}`}
onClick={() => setCategory(cat)}
>
{cat.charAt(0).toUpperCase() + cat.slice(1)}
</button>
))}
</div>

<div className="max-w-3xl mx-auto p-8 bg-[#171717] rounded-lg shadow-lg">
<div className="text-center">
<ImQuotesRight className="h-12 w-12 mx-auto mb-6" />
<p className="text-3xl italic font-light mb-4">
{quote}
</p>
<ImQuotesRight className="h-12 w-12 mx-auto mb-6" />
<p className="text-3xl italic font-light mb-4">{quote}</p>
<p className="text-xl font-semibold">- {author}</p>
</div>

<div className="flex justify-center space-x-4 mt-8">
<button
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white font-semibold rounded-md flex items-center space-x-2"
onClick={getNewQuote}
onClick={fetchQuote}
>
<ImQuotesRight className="w-5 h-5" /> <span>New Quote</span>
</button>
Expand All @@ -72,7 +89,11 @@ export default function DailyQuote() {
<RiFileCopyLine className="w-5 h-5" /> <span>Copy</span>
</button>
</div>
{copied && <p className="text-green-300 text-center mt-8">Copied successfully!</p>}
{copied && (
<p className="text-green-300 text-center mt-8">
Copied successfully!
</p>
)}
</div>

<footer className="text-center text-sm text-gray-500 mt-16">
Expand Down
Loading
Loading