Skip to content

Commit 0e2bf84

Browse files
committed
Better overview page
1 parent 8200102 commit 0e2bf84

File tree

8 files changed

+394
-158
lines changed

8 files changed

+394
-158
lines changed

app/actions/reviewEvents.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use server';
2+
3+
import { ObjectId } from 'mongodb';
4+
import { connectToDatabase } from '@/lib/db';
5+
import { ReviewEventDocument, ReviewResult, CardDocument } from '@/types';
6+
7+
interface LastReviewResult {
8+
cardId: string;
9+
lastResult: ReviewResult;
10+
timestamp: Date;
11+
}
12+
13+
// Fetches the most recent review event for each card within a specific deck.
14+
export async function getLastReviewEventPerCard(deckId: string): Promise<Map<string, LastReviewResult>> {
15+
if (!deckId || !ObjectId.isValid(deckId)) {
16+
throw new Error('Invalid Deck ID provided.');
17+
}
18+
19+
const { db } = await connectToDatabase();
20+
const reviewEventsCollection = db.collection<ReviewEventDocument>('review_events');
21+
const cardsCollection = db.collection<CardDocument>('cards');
22+
23+
try {
24+
// 1. Find all card IDs belonging to the deck
25+
const cardIdsInDeck = await cardsCollection
26+
.find({ deck_id: new ObjectId(deckId) }, { projection: { _id: 1 } })
27+
.map((doc: { _id: ObjectId }) => doc._id)
28+
.toArray();
29+
30+
if (cardIdsInDeck.length === 0) {
31+
return new Map(); // No cards in deck, so no review history
32+
}
33+
34+
// 2. Use aggregation to find the last review event for each relevant card
35+
const aggregationPipeline = [
36+
// Match only events for cards in the target deck
37+
{ $match: { card_id: { $in: cardIdsInDeck } } },
38+
// Sort by timestamp descending to get the latest first
39+
{ $sort: { timestamp: -1 } },
40+
// Group by card_id and take the first document (which is the latest due to sorting)
41+
{
42+
$group: {
43+
_id: "$card_id",
44+
lastEvent: { $first: "$$ROOT" } // Get the whole document
45+
}
46+
},
47+
// Reshape the output
48+
{
49+
$project: {
50+
_id: 0, // Exclude the grouping _id
51+
cardId: { $toString: "$_id" }, // Convert card_id ObjectId to string
52+
lastResult: "$lastEvent.result",
53+
timestamp: "$lastEvent.timestamp"
54+
}
55+
}
56+
];
57+
58+
const results: LastReviewResult[] = await reviewEventsCollection.aggregate<LastReviewResult>(aggregationPipeline).toArray();
59+
60+
// Convert the array of results into a Map for easy lookup by cardId
61+
const resultMap = new Map<string, LastReviewResult>();
62+
results.forEach(item => {
63+
resultMap.set(item.cardId, item);
64+
});
65+
66+
return resultMap;
67+
68+
} catch (error) {
69+
console.error("Error fetching last review events:", error);
70+
throw new Error("Failed to fetch review history.");
71+
}
72+
}

app/deck/[deckId]/edit/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ export default function EditDeckPage() {
173173
<div className="flex justify-between items-center">
174174
<h1 className="text-3xl font-bold text-primary truncate">Edit Deck: {deck?.name || deckId}</h1>
175175
<div className="flex space-x-2">
176-
<Link href={`/deck/${deckId}/options`} passHref legacyBehavior>
177-
<Button as="a" variant="secondary">Play / View History</Button>
176+
<Link href={`/deck/${deckId}/overview`} passHref legacyBehavior>
177+
<Button as="a" variant="secondary">Back to Overview</Button>
178178
</Link>
179179
{/* TODO: Add Edit Deck Name Button/Modal */}
180180
</div>

app/deck/[deckId]/options/page.tsx

Lines changed: 0 additions & 123 deletions
This file was deleted.

0 commit comments

Comments
 (0)