diff --git a/backend/prisma/migrations/20240713163709_thought/migration.sql b/backend/prisma/migrations/20240713163709_thought/migration.sql
new file mode 100644
index 0000000..c75d822
--- /dev/null
+++ b/backend/prisma/migrations/20240713163709_thought/migration.sql
@@ -0,0 +1,13 @@
+-- CreateTable
+CREATE TABLE "Thought" (
+ "id" TEXT NOT NULL,
+ "content" TEXT NOT NULL,
+ "publishedDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "published" BOOLEAN NOT NULL DEFAULT false,
+ "authorId" TEXT NOT NULL,
+
+ CONSTRAINT "Thought_pkey" PRIMARY KEY ("id")
+);
+
+-- AddForeignKey
+ALTER TABLE "Thought" ADD CONSTRAINT "Thought_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma
index 86d94cd..06abd24 100644
--- a/backend/prisma/schema.prisma
+++ b/backend/prisma/schema.prisma
@@ -28,6 +28,7 @@ model User {
comments Comment[]
subscribers Subscriber[] @relation("UserSubscribers")
subscribedTo Subscriber[] @relation("UserSubscribedTo")
+ thoughts Thought[]
}
model Post {
@@ -100,3 +101,12 @@ model Subscriber {
user User @relation("UserSubscribers", fields: [userId], references: [id])
subscriber User @relation("UserSubscribedTo", fields: [subscriberId], references: [id])
}
+
+ model Thought {
+ id String @id @default(uuid())
+ content String
+ publishedDate DateTime @default(now())
+ published Boolean @default(false)
+ author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
+ authorId String
+}
\ No newline at end of file
diff --git a/backend/src/index.ts b/backend/src/index.ts
index beec1bd..4a3d650 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -7,6 +7,7 @@ import { clapRouter } from "./routes/clap";
import { tagRouter } from "./routes/tag";
import { subscriberRouter } from "./routes/subscriber";
import { commentRouter } from "./routes/comments";
+import { thoughtRouter } from "./routes/thought";
const app = new Hono<{
Bindings: {
@@ -22,5 +23,6 @@ app.route('/api/v1/clap', clapRouter)
app.route('/api/v1/tag', tagRouter)
app.route('/api/v1/subscriber', subscriberRouter)
app.route("/api/v1/comments", commentRouter)
+app.route("/api/v1/thought", thoughtRouter)
export default app;
diff --git a/backend/src/routes/thought.ts b/backend/src/routes/thought.ts
new file mode 100644
index 0000000..f56d8d5
--- /dev/null
+++ b/backend/src/routes/thought.ts
@@ -0,0 +1,200 @@
+import { Hono } from "hono";
+import { verify } from "hono/jwt";
+import { getDBInstance } from "../db/util";
+
+/**
+ *
+ * Introducing Thoughts. User can write a thought. Thoughts are short form. Think of 1 Thought like a Twitter post or Threads post.
+ *
+ * thoughtRouter.post
+thoughtRouter.put
+thoughtRouter.get: 1 and all
+thoughtRouter.delete
+ */
+export const thoughtRouter = new Hono<{
+ Bindings: {
+ DATABASE_URL: string;
+ JWT_SECRET: string;
+ };
+ Variables: {
+ userId: string;
+ };
+}>();
+
+
+//get all thoughts of a user
+thoughtRouter.get("/all/:userId", async (c) => {
+ try {
+ const prisma = getDBInstance(c)
+ const userId = await c.req.param("userId");
+ const thoughts = await prisma.thought.findMany({
+ where: {
+ authorId: userId,
+ },
+ select: {
+ authorId: true,
+ content: true,
+ id: true,
+ published: true,
+ publishedDate: true,
+ author: {
+ select: {
+ name: true
+ }
+ }
+
+ }
+ });
+
+ return c.json({
+ thoughts: thoughts
+ });
+ } catch (e) {
+ c.status(411);
+ return c.json({
+ message: "Error while fetching thoughts",
+ error: e,
+ });
+ }
+
+})
+
+//get a thought of a user
+thoughtRouter.get("/:thoughtId", async (c) => {
+ try {
+ const prisma = getDBInstance(c)
+ const thoughtId = c.req.param("thoughtId");
+ const thought = await prisma.thought.findFirst({
+ where: {
+ id: thoughtId,
+ },
+ select: {
+ authorId: true,
+ content: true,
+ id: true,
+ published: true,
+ publishedDate: true,
+ author: {
+ select: {
+ name: true
+ }
+ }
+
+
+ }
+ });
+
+ return c.json({
+ thought: thought
+ });
+ } catch (e) {
+ c.status(411);
+ return c.json({
+ message: "Error while fetching thought",
+ error: e,
+ });
+ }
+
+})
+
+//protect all the routes below this
+thoughtRouter.use("/*", async (c, next) => {
+ try {
+ const header = c.req.header("authorization") || "";
+ const token = header.split(" ")[1];
+ const user = await verify(token, c.env.JWT_SECRET);
+ if (user && typeof user.id === "string") {
+ c.set("userId", user.id);
+ return next();
+ } else {
+ c.status(403);
+ return c.json({ error: "Unauthorized " });
+ }
+ } catch (e) {
+ c.status(403);
+ return c.json({
+ error: "Credentials failed",
+ });
+ }
+});
+
+//create thought
+thoughtRouter.post("/create", async (c) => {
+ try {
+ const prisma = getDBInstance(c)
+ const userId = c.get("userId");
+ const body = await c.req.json();
+ const { content } = body;
+ if (!content) {
+ c.status(400);
+ return c.json({
+ message: "Content is required",
+ });
+ }
+ const thought = await prisma.thought.create({
+ data: {
+ authorId: userId,
+ content: content,
+ },
+ });
+
+ return c.json({
+ id: thought.id
+ });
+ } catch (e) {
+ c.status(403);
+ return c.json({ error: "Something went wrong ", stackTrace: e });
+ }
+})
+
+//update thought
+thoughtRouter.put("/update", async (c) => {
+ try {
+ const prisma = getDBInstance(c)
+ const body = await c.req.json();
+ const { id, content } = body;
+ if (!content || !id) {
+ c.status(400);
+ return c.json({
+ message: "Please provide all required values",
+ });
+ }
+ const thought = await prisma.thought.update({
+ where: {
+ id: id,
+ },
+ data: {
+ content: content,
+ },
+ });
+
+ return c.json({
+ id: thought.id
+ });
+ } catch (e) {
+ c.status(403);
+ return c.json({ error: "Something went wrong ", stackTrace: e });
+ }
+})
+
+//to delete a thought
+thoughtRouter.delete("/:thoughtId", async (c) => {
+ try {
+ const prisma = getDBInstance(c)
+ const thoughtId = c.req.param("thoughtId");
+ await prisma.thought.delete({
+ where: {
+ id: thoughtId,
+ },
+ });
+
+ return c.json({
+ message: "Thought deleted successfully",
+ });
+ } catch (e) {
+ c.status(411);
+ return c.json({
+ message: "Error while deleting post",
+ });
+ }
+})
\ No newline at end of file
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 0a671a0..c3a4520 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -2,6 +2,7 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { lazy, Suspense } from 'react';
import Spinner from './components/Spinner';
import { ThemeProvider } from '@/components/theme-provider';
+import Thought from './pages/Thought';
// const Home = lazy(() => import('./pages/Home'));
const Signup = lazy(() => import('./pages/Signup'));
const Signin = lazy(() => import('./pages/Signin'));
@@ -30,12 +31,13 @@ function App() {