A comprehensive full-stack web application for managing YouTube videos, built with Next.js 14, TypeScript, and Tailwind CSS.
- Video Management: View and edit video details, statistics, and metadata
- Comment Management: Read, create, reply to, and delete comments
- Notes System: Take and organize searchable notes with tagging
- Event Logging: Track all user interactions for audit purposes
- Secure Authentication: Google OAuth integration with NextAuth.js
- Frontend: Next.js 14 (App Router), React 18, TypeScript
- Styling: Tailwind CSS, shadcn/ui components
- Authentication: NextAuth.js with Google OAuth
- Database: Prisma ORM with SQLite (dev) / PostgreSQL (prod)
- API Integration: YouTube Data API v3
- Node.js 18+
- npm or yarn
- Google Cloud Console project with YouTube Data API enabled
- Google OAuth credentials
- Clone the repository:
git clone <repository-url>
cd youtube-companion-dashboard- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env.local- Configure your
.env.localfile with:
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret-here
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
YOUTUBE_API_KEY=your-youtube-api-key
DATABASE_URL="file:./dev.db"
NODE_ENV=development- Run the development server:
npm run dev- Open http://localhost:3000 in your browser.
npm run dev- Start development server with Turbopacknpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run lint:fix- Fix ESLint issuesnpm run format- Format code with Prettiernpm run format:check- Check code formattingnpm run type-check- Run TypeScript type checking
src/
├── app/ # Next.js App Router pages
├── components/
│ ├── ui/ # shadcn/ui components
│ ├── layout/ # Layout components
│ └── features/ # Feature-specific components
├── lib/
│ ├── services/ # API services
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ └── config.ts # Application configuration
└── ...
GET /api/auth/session- Get current user session (NextAuth)POST /api/auth/signin- Sign in with Google OAuth (NextAuth)POST /api/auth/signout- Sign out current user (NextAuth)
GET /api/health- Health check with auth and environment status
GET /api/user- Get authenticated user summary and access token statusGET /api/user/profile- Get user profilePUT /api/user/profile- Update display name or username
GET /api/notes- List notes with search and pagination- Query:
query,tags(comma-separated),videoId,page,limit(≤100),orderBy(createdAt|updatedAt|content),orderDirection(asc|desc)
- Query:
POST /api/notes- Create note- Body:
videoId(string),content(string),tags(string[] optional)
- Body:
GET /api/notes/[noteId]- Get note by IDPUT /api/notes/[noteId]- Update content, tags, or videoIdDELETE /api/notes/[noteId]- Delete noteGET /api/notes/search- Enhanced search with relevance and highlights- Query:
query,tags,videoId,page,limit(≤100),orderBy(createdAt|updatedAt|content|relevance),orderDirection,includeHighlights(boolean)
- Query:
GET /api/notes/suggestions- Search suggestions- Query:
query(required),limit(≤20),type(content|tags|both)
- Query:
GET /api/notes/tags- All unique tags for user
GET /api/youtube/video?id=...- Public video details by ID (no auth)GET /api/youtube/video/[videoId]- Authenticated video details with ownership validationPUT /api/youtube/video/[videoId]/update- Update video title/description (auth)GET /api/youtube/videos- Authenticated user's videos (maxResults1–50,pageToken)GET /api/youtube/channel- Authenticated user's channel infoGET /api/youtube/comments?id=...- Public comments for a video (maxResults,pageToken)POST /api/youtube/comments- Post comment or reply (auth)DELETE /api/youtube/comments/[commentId]- Delete comment (auth)
GET /api/events- Event logs with filters and pagination- Query:
page,limit,eventType,entityType,entityId,startDate,endDate,orderBy,orderDirection
- Query:
GET /api/events/analytics- Summary, timeline, top events, recent activity- Query:
period(day|week|month|year),startDate,endDate,groupBy
- Query:
GET /api/events/stats- Aggregated counts pereventTypePOST /api/events/track- Track an event (auth)- Body:
eventType,entityType,entityId, optionalmetadata
- Body:
Dev (SQLite)
model User {
id String @id @default(cuid())
name String?
displayName String?
username String?
email String @unique
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
accounts Account[]
sessions Session[]
notes Note[]
eventLogs EventLog[]
@@map("users")
}
model Note {
id String @id @default(cuid())
videoId String
content String
tags String // JSON string for SQLite
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([videoId])
@@index([userId])
@@index([content])
@@index([tags])
@@index([userId, videoId])
@@index([userId, createdAt])
@@map("notes")
}
model EventLog {
id String @id @default(cuid())
eventType String
entityType String
entityId String
metadata String? // JSON string for SQLite
timestamp DateTime @default(now())
ipAddress String?
userAgent String?
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([eventType])
@@index([timestamp])
@@map("event_logs")
}Prod (PostgreSQL)
model User {
id String @id @default(cuid())
email String @unique
name String?
image String?
googleId String @unique
accessToken String?
refreshToken String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notes Note[]
eventLogs EventLog[]
@@map("users")
}
model Note {
id String @id @default(cuid())
videoId String
content String
tags String[] // PostgreSQL array
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([videoId])
@@index([userId])
@@map("notes")
}
model EventLog {
id String @id @default(cuid())
eventType String
entityType String
entityId String
metadata Json? // PostgreSQL JSON
timestamp DateTime @default(now())
ipAddress String?
userAgent String?
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([eventType])
@@index([timestamp])
@@map("event_logs")
}- SQLite (development):
tagsstored as JSON strings;metadatastored asString?. - PostgreSQL (production):
tagsasString[];metadataasJson?. - API endpoints normalize tags and metadata across providers for consistent responses.
video_viewed- Video was viewed/loadedvideo_played- Video playback startedvideo_paused- Video playback pausedvideo_seeked- Video timeline was seeked
note_created- New note was creatednote_updated- Existing note was modifiednote_deleted- Note was deleted
search_performed- Search query was executedsearch_suggestion_clicked- Search suggestion was selected
page_view- Page was visitedbutton_click- Button was clickedform_submit- Form was submittedmodal_open- Modal dialog was openedmodal_close- Modal dialog was closed
api_error- Server-side API error occurredclient_error- Client-side JavaScript errornetwork_error- Network connectivity issue
user- User-related eventsvideo- YouTube video-related eventsnote- Note-related eventscomment- Comment-related eventspage- Page navigation eventsbutton- UI button interactionsform- Form interactionsmodal- Modal dialog eventssearch- Search-related eventssystem- System/application events
| Variable | Description | Required |
|---|---|---|
NEXTAUTH_URL |
Application URL | Yes |
NEXTAUTH_SECRET |
NextAuth.js secret key | Yes |
GOOGLE_CLIENT_ID |
Google OAuth client ID | Yes |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret | Yes |
YOUTUBE_API_KEY |
YouTube Data API key | Yes |
DATABASE_URL |
Database connection string | Yes |
- Create a new project in Google Cloud Console
- Enable the YouTube Data API v3
- Create credentials (API key for YouTube API)
- Create OAuth 2.0 credentials for web application
- Add authorized redirect URIs:
http://localhost:3000/api/auth/callback/google
The application requires the following YouTube API scopes:
https://www.googleapis.com/auth/youtube.readonlyhttps://www.googleapis.com/auth/youtube.force-ssl
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
This project is licensed under the MIT License.