diff --git a/src/app/api/daily-note/route.ts b/src/app/api/daily-note/route.ts
new file mode 100644
index 00000000..48ce9627
--- /dev/null
+++ b/src/app/api/daily-note/route.ts
@@ -0,0 +1,121 @@
+import { NextResponse ,NextRequest} from "next/server";
+import { supabaseAdmin } from "@/lib/supabase";
+import { getToken } from "next-auth/jwt";
+
+export async function GET(req: NextRequest){
+
+ try{
+ const token = await getToken({
+ req,
+ secret: process.env.NEXTAUTH_SECRET,
+ });
+ console.log(token)
+
+ const userId = token?.githubId;
+
+ if(!userId){
+ return NextResponse.json(
+ {error: `Unauthorized`},
+ {status: 400}
+ );
+ }
+
+ const today = new Date();
+ const todayDate = today.toISOString().split("T")[0];
+
+ const yesterday = new Date();
+ yesterday.setDate(yesterday.getDate() -1);
+
+ const yesterdayDate = yesterday.toISOString().split("T")[0];
+
+ const {data : todayData} = await supabaseAdmin
+ .from("daily_notes")
+ .select("*")
+ .eq("user_id",userId)
+ .eq("date",todayDate)
+ .single();
+
+ const {data : yesterdayData} = await supabaseAdmin
+ .from("daily_notes")
+ .select("*")
+ .eq("user_id",userId)
+ .eq("date",yesterdayDate)
+ .single();
+ console.log(todayData,yesterdayData);
+ return NextResponse.json({
+ todayNote: todayData?.note || "",
+ yesterdayNote: yesterdayData?.note || "",
+ });
+
+ }catch(error){
+ return NextResponse.json(
+ {error: `Something went wrong `},
+ {status: 500}
+ );
+
+ }
+}
+
+export async function POST(req: NextRequest) {
+ try{
+
+ const token = await getToken({
+ req,
+ secret: process.env.NEXTAUTH_SECRET,
+ });
+ console.log(token)
+
+ const userId = token?.githubId;
+ const body = await req.json();
+ console.log(body);
+ const { note} = body;
+ if(!userId){
+ console.log("no user id");
+ return NextResponse.json(
+ {error: "User id is requied "},
+ {status: 400}
+ );
+ }
+ if(!note || !note.trim()){
+ console.log("no note ");
+ return NextResponse.json(
+ {error: "Note cannot be empty"},
+ {status: 400}
+ );
+ }
+ if(note.length >280){
+ console.log("max len ");
+ return NextResponse.json(
+ {error: "Maximum 280 characters allowed"},
+ {status: 400}
+ );
+ }
+ const today = new Date().toISOString().split("T")[0];
+ const {data, error} = await supabaseAdmin
+ .from("daily_notes")
+ .upsert({
+ user_id: userId,
+ date: today,
+ note: note.trim(),
+ },{
+ onConflict:"user_id,date"
+ })
+ .select()
+ .single();
+ if(error){
+ console.log(error.message);
+ return NextResponse.json(
+ {error: error.message},
+ {status:500}
+ );
+ }
+ console.log(data);
+ return NextResponse.json(data);
+ }catch(error){
+ console.log(error);
+ return NextResponse.json(
+ {error: "Something went wrong"},
+ {status:500}
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 08f0d988..6bf8254c 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -96,6 +96,19 @@ const PRReviewTrendChart = dynamic(
() => import("@/components/PRReviewTrendChart"),
{ ssr: false, loading: () => },
);
+import WeeklySummaryCard from "@/components/WeeklySummaryCard";
+import { AIMentorWidget } from "@/components/AIMentorWidget";
+import ExportButton from "@/components/ExportButton";
+import Link from "next/link";
+import PersonalRecords from "@/components/PersonalRecords";
+import LocalCodingTime from "@/components/LocalCodingTime";
+import CodingTimeWidget from "@/components/CodingTimeWidget";
+import RecentActivity from "@/components/RecentActivity";
+import { authOptions } from "@/lib/auth";
+import { getServerSession } from "next-auth";
+import { redirect } from "next/navigation";
+import DailyNoteWidget from "@/components/DailyNoteWidget";
+import DashboardSSEProvider from "@/components/DashboardSSEProvider";
export default async function DashboardPage() {
const session = await getServerSession(authOptions);
@@ -170,6 +183,15 @@ export default async function DashboardPage() {
+
+
+
+
+
+
+
+ {/* Row 2: PR metrics, community metrics, PR breakdown & Time Chart */}
+
{/* ── Row 2: PR metrics + Community metrics ── */}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 457788be..ef74e051 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -91,7 +91,6 @@ async function fetchRepoStats(): Promise
{
export default async function HomePage() {
const session = await getServerSession(authOptions);
-
if (session) {
redirect("/dashboard");
}
diff --git a/src/components/DailyNoteWidget.tsx b/src/components/DailyNoteWidget.tsx
new file mode 100644
index 00000000..77388c48
--- /dev/null
+++ b/src/components/DailyNoteWidget.tsx
@@ -0,0 +1,126 @@
+"use client";
+
+import { useEffect, useState } from "react";
+
+export default function DailyNoteWidget(){
+
+ const [loading,setLoading] = useState(false);
+ const [note,setNote] = useState("");
+ const [yesterdayNote, setYesterdayNote] = useState("");
+ const [showYesterday,setShowYesterday] = useState(false);
+
+ useEffect(()=>{
+
+ const fetchNotes = async ()=>{
+
+ try{
+ setLoading(true);
+
+ const response = await fetch("/api/daily-note");
+
+ const data = await response.json();
+ setNote(data.todayNote||"");
+ setYesterdayNote(data.yesterdayNote ||"" );
+
+ }catch(error){
+ console.error("Failed to fetch notes");
+ }finally{
+ setLoading(false);
+ }
+
+ };
+ fetchNotes();
+ },[]);
+
+
+// auto save with debounce
+const debounceFunction = async()=>{
+
+ if(!note.trim()) return ;
+
+ try{
+ await fetch("/api/daily-note",{
+ method:"POST",
+ headers:{
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ note,
+ }),
+ });
+ }catch(error){
+ console.error("Failed to save note");
+ }
+}
+useEffect(()=>{
+
+ const timeout= setTimeout(()=>{
+ debounceFunction();
+ },500);
+ return ()=>clearTimeout(timeout);
+},[note]);
+
+
+if (loading) {
+ return (
+
+ );
+}
+
+ return(
+
+
+
+
+ Today's Plan` `
+
+
+
Plan your coding session.
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/supabase/migrations/20260515000002_add_daily_notes.sql b/supabase/migrations/20260515000002_add_daily_notes.sql
new file mode 100644
index 00000000..390ad427
--- /dev/null
+++ b/supabase/migrations/20260515000002_add_daily_notes.sql
@@ -0,0 +1,10 @@
+
+create table if not exists daily_notes (
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+ user_id text not null,
+ date date not null,
+ note text,
+ created_at timestamptz default now(),
+
+ UNIQUE(user_id, date)
+);
\ No newline at end of file
diff --git a/supabase/schema.sql b/supabase/schema.sql
index 80d4b809..79aab233 100644
--- a/supabase/schema.sql
+++ b/supabase/schema.sql
@@ -62,6 +62,16 @@ create index if not exists idx_ai_insights_type on ai_insights(insight_type);
create unique index if not exists idx_ai_insights_user_type
on ai_insights(user_id, insight_type);
+-- daily_notes schema--
+create table if not exists daily_notes (
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+ user_id text not null,
+ date date not null,
+ note text,
+ created_at timestamptz default now(),
+
+ UNIQUE(user_id, date)
+);
create table if not exists user_github_achievements (
user_id text primary key references users(id) on delete cascade,
github_login text not null,