Skip to content

Commit

Permalink
Merge pull request #93 from evgongora/fix/flow-errors
Browse files Browse the repository at this point in the history
fix: flow errors and new features
  • Loading branch information
evgongora authored Jan 26, 2025
2 parents 95822c6 + fb5318b commit 2c2bf86
Show file tree
Hide file tree
Showing 12 changed files with 494 additions and 139 deletions.
23 changes: 21 additions & 2 deletions frontend/src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,30 @@ import QuizCard from "@/components/ui/QuizCard";
import { AchievementButton } from "@/components/ui/AchievementButton"
import { LeaderboardButton } from "@/components/ui/LeaderboardButton"

interface User {
name: string;
last_name: string;
level: string;
points: number;
maxPoints: number;
}

export default function Home() {
const [loading, setLoading] = useState(true)
const [userData, setUserData] = useState<User | null>(null)

useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/api/home')
await response.json()
if (!response.ok) {
const errorData = await response.json()
console.error('API Error:', errorData)
return
}
const data = await response.json()
console.log('Received user data:', data) // Debug log
setUserData(data.user)
} catch (error) {
console.error('Error fetching home data:', error)
} finally {
Expand Down Expand Up @@ -46,7 +62,10 @@ export default function Home() {
<div className="w-full max-w-7xl px-4">
<div className="flex flex-col gap-6 items-center w-full">
<div className="w-full flex justify-center">
<ProfileCard className="w-full max-w-[365px] transform transition-all duration-300 hover:scale-105" />
<ProfileCard
className="w-full max-w-[365px] transform transition-all duration-300 hover:scale-105"
user={userData || undefined}
/>
</div>

<div className="w-full flex justify-center">
Expand Down
52 changes: 52 additions & 0 deletions frontend/src/app/api/home/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getXataClient } from "@/lib/utils";
import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { cookies } from 'next/headers';
import { jwtVerify } from 'jose';

const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET) {
throw new Error('JWT_SECRET environment variable is required');
}

const secret = new TextEncoder().encode(JWT_SECRET);

export async function GET() {
try {
// Try NextAuth session first
const session = await getServerSession();
const xata = getXataClient();
let user;

if (session?.user?.email) {
user = await xata.db.Users.filter({ email: session.user.email }).getFirst();
} else {
// Try JWT session from wallet auth
const token = cookies().get('session')?.value;

if (token) {
const { payload } = await jwtVerify(token, secret);
if (payload.address) {
user = await xata.db.Users.filter({ wallet_address: payload.address }).getFirst();
}
}
}

if (!user) {
return NextResponse.json({ error: "User not found" }, { status: 404 });
}

return NextResponse.json({
user: {
name: user.name,
last_name: user.last_name,
level: "Coming Soon",
points: 45,
maxPoints: 100
}
});
} catch (error) {
console.error('Error in home API route:', error);
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}
79 changes: 79 additions & 0 deletions frontend/src/app/api/tests/[testId]/questions/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { getXataClient } from "@/lib/utils";
import { NextResponse } from "next/server";
import { Question } from "@/app/types";

export async function GET(
request: Request,
{ params }: { params: { testId: string } }
) {
try {
const testId = parseInt(params.testId);

if (isNaN(testId) || testId <= 0) {
return NextResponse.json(
{ error: "Invalid test ID" },
{ status: 400 }
);
}

const xata = getXataClient();

// First, verify the total questions in the test
const test = await xata.db.Tests
.filter({ test_id: testId })
.getFirst();

if (!test) {
return NextResponse.json(
{ error: "Test not found" },
{ status: 404 }
);
}

console.log(`Expected questions for test ${testId}:`, test.total_questions);

// Fetch questions with explicit pagination
const questions = await xata.db.Questions
.filter({
"test.test_id": testId
})
.sort("sort_order", "asc")
.getPaginated({
pagination: {
size: 100 // Increase the limit to ensure we get all questions
}
});

console.log(`Actually fetched questions:`, questions.records.length);

if (!questions.records || questions.records.length === 0) {
return NextResponse.json(
{ error: "No questions found for this test" },
{ status: 404 }
);
}

// Transform the questions to match the expected format
const formattedQuestions = questions.records.map(q => ({
id: q.question_id,
question: q.question,
effect: {
econ: 0, // Add your actual effect values here
dipl: 0,
govt: 0,
scty: 0
}
}));

return NextResponse.json({
questions: formattedQuestions
});

} catch (error) {
console.error("Error in questions API:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
81 changes: 74 additions & 7 deletions frontend/src/app/ideology-test/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { useState, useEffect } from "react";
import { FilledButton } from "@/components/ui/FilledButton";
import { ProgressBar } from "@/components/ui/ProgressBar";
import { useRouter } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { Question } from "@/app/types";
import { TestResult } from "@/app/types";

Expand All @@ -17,6 +17,9 @@ const answers = [

export default function IdeologyTest() {
const router = useRouter();
const searchParams = useSearchParams();
const testId = searchParams.get('testId') || '1';

const [currentQuestion, setCurrentQuestion] = useState(0);
const [questions, setQuestions] = useState<Question[]>([]);
const [scores, setScores] = useState({ econ: 0, dipl: 0, govt: 0, scty: 0 });
Expand All @@ -30,23 +33,51 @@ export default function IdeologyTest() {
console.log("Fetching questions...");
const fetchQuestions = async () => {
try {
const response = await fetch(`/api/questions/ideology-test`);
const response = await fetch(`/api/tests/${testId}/questions`);
if (!response.ok) {
throw new Error("Failed to fetch questions");
const errorData = await response.json();
throw new Error(errorData.error || "Failed to fetch questions");
}
const data = await response.json();

if (!data.questions || !Array.isArray(data.questions)) {
throw new Error("Invalid response format");
}

console.log("Questions fetched:", data.questions);
setQuestions(data.questions);
} catch (err) {
console.error("Error fetching questions:", err);
setError(err instanceof Error ? err.message : "An unknown error occurred");
const errorMessage = err instanceof Error ? err.message : "An unknown error occurred";
console.error("Error fetching questions:", errorMessage);
setError(errorMessage);
} finally {
setLoading(false);
}
};

fetchQuestions();
}, []);
if (testId) {
fetchQuestions();
}
}, [testId]);

useEffect(() => {
const loadSavedProgress = async () => {
try {
const response = await fetch(`/api/tests/${testId}/progress`);
if (response.ok) {
const data = await response.json();
if (data.currentQuestion > 0) {
setCurrentQuestion(data.currentQuestion);
setScores(data.scores);
}
}
} catch (error) {
console.error('Error loading saved progress:', error);
}
};

loadSavedProgress();
}, [testId]);

const handleAnswer = async (multiplier: number) => {
if (questions.length === 0) return;
Expand All @@ -60,6 +91,29 @@ export default function IdeologyTest() {
};
setScores(updatedScores);

// Save progress to database
try {
const response = await fetch(`/api/tests/${testId}/progress`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
questionId: question.id,
answer: multiplier,
currentQuestion: currentQuestion,
scores: updatedScores
})
});

if (!response.ok) {
throw new Error('Failed to save progress');
}
} catch (error) {
console.error('Error saving progress:', error);
// Optionally show error to user
}

if (currentQuestion < questions.length - 1) {
setCurrentQuestion(currentQuestion + 1);
} else {
Expand All @@ -80,6 +134,19 @@ export default function IdeologyTest() {
scty: sctyScore,
};

// Save final results
try {
await fetch(`/api/tests/${testId}/complete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ results })
});
} catch (error) {
console.error('Error saving final results:', error);
}

// Redirect to insights page with results
router.push(`/insights?econ=${results.econ}&dipl=${results.dipl}&govt=${results.govt}&scty=${results.scty}`);
}
Expand Down
Loading

0 comments on commit 2c2bf86

Please sign in to comment.