Development Environment
FlashMind is built with a modern development stack that makes it easy to customize and extend.
Project Structure
flash/
├── app/ # Next.js app directory
│ ├── api/ # API routes
│ ├── dashboard/ # Dashboard pages
│ ├── deck/ # Deck management pages
│ └── ...
├── components/ # Reusable React components
├── convex/ # Backend functions and schema
├── lib/ # Utility functions
├── hooks/ # Custom React hooks
└── public/ # Static assets
Key Technologies
FlashMind uses Next.js with the App Router for:
- Server-side rendering
- API routes
- File-based routing
- Built-in optimizations
Convex provides:
- Real-time database
- Serverless functions
- Automatic API generation
- Type-safe queries and mutations
Clerk handles:
- User authentication
- Session management
- User profiles
- Multi-factor authentication
Tailwind CSS enables:
- Utility-first styling
- Responsive design
- Dark mode support
- Custom design system
Customization
Styling
FlashMind uses Tailwind CSS with a custom design system. You can customize:
/* Custom color palette */
:root {
--primary: 9 146 104;
--primary-foreground: 255 255 255;
--secondary: 240 244 248;
--secondary-foreground: 15 23 42;
}
Database Schema
Modify the Convex schema to add new fields or tables:
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
decks: defineTable({
title: v.string(),
description: v.optional(v.string()),
userId: v.string(),
isPublic: v.optional(v.boolean()),
tags: v.optional(v.array(v.string())), // Add custom fields
}),
cards: defineTable({
front: v.string(),
back: v.string(),
deckId: v.id("decks"),
difficulty: v.optional(v.number()), // Custom field
}),
});
Spaced Repetition Algorithm
The spaced repetition algorithm can be customized in convex/spacedRepetition.ts:
export function calculateNextReview(
quality: number,
repetitions: number,
easeFactor: number,
interval: number
): ReviewResult {
// Customize the algorithm parameters
const minimumEaseFactor = 1.3;
const easeFactorIncrement = 0.1;
// Your custom logic here
}
Adding Features
Creating New Pages
- Add a new page in the
app/ directory:
export default function AnalyticsPage() {
return (
<div>
<h1>Analytics Dashboard</h1>
{/* Your component here */}
</div>
);
}
- Add navigation in
components/navigation.tsx
Creating Convex Functions
Add new backend functions in the convex/ directory:
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getStudyStats = query({
args: { userId: v.string() },
returns: v.object({
totalCards: v.number(),
studiedToday: v.number(),
streak: v.number(),
}),
handler: async (ctx, args) => {
// Implementation
},
});
Adding Components
Create reusable components in the components/ directory:
components/study-streak.tsx
interface StudyStreakProps {
streak: number;
}
export function StudyStreak({ streak }: StudyStreakProps) {
return (
<div className="flex items-center gap-2">
<span>🔥</span>
<span>{streak} day streak</span>
</div>
);
}
Testing
Running Tests
Writing Tests
Create tests alongside your components:
__tests__/study-streak.test.tsx
import { render, screen } from '@testing-library/react';
import { StudyStreak } from '@/components/study-streak';
describe('StudyStreak', () => {
it('displays the correct streak count', () => {
render(<StudyStreak streak={5} />);
expect(screen.getByText('5 day streak')).toBeInTheDocument();
});
});
Deployment
Environment Variables
Set up your production environment variables:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...
CLERK_SECRET_KEY=sk_live_...
CONVEX_DEPLOYMENT=prod:...
Build and Deploy
Deploy frontend
Deploy to Vercel, Netlify, or your preferred platform
Consider setting up GitHub Actions for automatic deployments when you push to your main branch.