feat: Add JWT authentication to backend, configure frontend API client, fix streak layout

This commit is contained in:
2026-09-23 12:11:44 +05:30
parent ea03846b9c
commit a3e430cb67
27 changed files with 210 additions and 120 deletions

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useState, useRef, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
@@ -66,7 +67,7 @@ export function AITutorChat() {
try {
const activeId = user?.id || (typeof window !== "undefined" ? localStorage.getItem("activeUserId") : null) || DEFAULT_USER_ID;
const res = await fetch('/api/ai-coach/chat/stream', {
const res = await fetchWithAuth('/api/ai-coach/chat/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: activeId, message: userText })

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useEffect, useState } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { RefreshCw, TrendingUp, MapPin, Star } from "lucide-react"
@@ -61,7 +62,7 @@ export function CollegePredictorCard() {
if (userLoading || !userId) return
async function fetchData() {
try {
const res = await fetch(`/api/ai-coach/readiness/${userId}`)
const res = await fetchWithAuth(`/api/ai-coach/readiness/${userId}`)
if (!res.ok) throw new Error("fallback")
} catch {
// Use mock data — no-op

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useEffect, useState } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { TrendingUp, Flame, RefreshCw } from "lucide-react"
@@ -18,7 +19,7 @@ export function ReadinessGauge() {
async function fetchReadiness() {
try {
const res = await fetch(`/api/ai-coach/readiness/${userId}`)
const res = await fetchWithAuth(`/api/ai-coach/readiness/${userId}`)
if (!res.ok) throw new Error("Failed to fetch")
const json = await res.json()
setData(json)

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useEffect, useState } from "react"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
@@ -16,7 +17,7 @@ export function ReferralCard() {
if (userLoading || !userId) return;
async function fetchReferral() {
try {
const res = await fetch(`/api/growth/referral/${userId}`)
const res = await fetchWithAuth(`/api/growth/referral/${userId}`)
if (res.ok) {
const json = await res.json()
setData(json)

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useEffect, useState } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { Check, RefreshCw } from "lucide-react"
@@ -17,7 +18,7 @@ export function StudyPlanCard() {
async function fetchPlan() {
try {
const res = await fetch(`/api/ai-coach/study-plan/today?user_id=${userId}`)
const res = await fetchWithAuth(`/api/ai-coach/study-plan/today?user_id=${userId}`)
if (!res.ok) {
// If no plan is generated yet, fallback silently
throw new Error("silent_fallback")

View File

@@ -1,5 +1,6 @@
"use client"
import { fetchWithAuth } from "@/lib/apiClient";
import { useState, useRef, useEffect } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { Send, Loader2, BrainCircuit, Sparkles } from "lucide-react"
@@ -49,7 +50,7 @@ export function TutorChat() {
setStreaming(true)
try {
const res = await fetch("/api/ai-coach/chat/stream", {
const res = await fetchWithAuth("/api/ai-coach/chat/stream", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: userId, message: text.trim() })