164 lines
4.5 KiB
TypeScript
164 lines
4.5 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { PrismaClient } from "@prisma/client";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
export const dynamic = "force-dynamic";
|
|
export const revalidate = 0;
|
|
|
|
interface ActivityStatusRow {
|
|
id: number;
|
|
activity_type?: string;
|
|
activity_details?: string;
|
|
activity_project?: string;
|
|
activity_language?: string;
|
|
activity_repo?: string;
|
|
music_playing?: boolean;
|
|
music_track?: string;
|
|
music_artist?: string;
|
|
music_album?: string;
|
|
music_platform?: string;
|
|
music_progress?: number;
|
|
music_album_art?: string;
|
|
watching_title?: string;
|
|
watching_platform?: string;
|
|
watching_type?: string;
|
|
gaming_game?: string;
|
|
gaming_platform?: string;
|
|
gaming_status?: string;
|
|
status_mood?: string;
|
|
status_message?: string;
|
|
updated_at: Date;
|
|
}
|
|
|
|
export async function GET() {
|
|
try {
|
|
// Check if table exists first
|
|
const tableCheck = await prisma.$queryRawUnsafe<Array<{ exists: boolean }>>(
|
|
`SELECT EXISTS (
|
|
SELECT FROM information_schema.tables
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'activity_status'
|
|
) as exists`
|
|
);
|
|
|
|
if (!tableCheck || !tableCheck[0]?.exists) {
|
|
// Table doesn't exist, return empty state
|
|
return NextResponse.json({
|
|
activity: null,
|
|
music: null,
|
|
watching: null,
|
|
gaming: null,
|
|
status: null,
|
|
});
|
|
}
|
|
|
|
// Fetch from activity_status table
|
|
const result = await prisma.$queryRawUnsafe<ActivityStatusRow[]>(
|
|
`SELECT * FROM activity_status WHERE id = 1 LIMIT 1`,
|
|
);
|
|
|
|
if (!result || result.length === 0) {
|
|
return NextResponse.json({
|
|
activity: null,
|
|
music: null,
|
|
watching: null,
|
|
gaming: null,
|
|
status: null,
|
|
});
|
|
}
|
|
|
|
const data = result[0];
|
|
|
|
// Check if activity is recent (within last 2 hours)
|
|
const lastUpdate = new Date(data.updated_at);
|
|
const now = new Date();
|
|
const hoursSinceUpdate =
|
|
(now.getTime() - lastUpdate.getTime()) / (1000 * 60 * 60);
|
|
const isRecent = hoursSinceUpdate < 2;
|
|
|
|
return NextResponse.json(
|
|
{
|
|
activity:
|
|
data.activity_type && isRecent
|
|
? {
|
|
type: data.activity_type,
|
|
details: data.activity_details,
|
|
project: data.activity_project,
|
|
language: data.activity_language,
|
|
repo: data.activity_repo,
|
|
link: data.activity_repo, // Use repo URL as link
|
|
timestamp: data.updated_at,
|
|
}
|
|
: null,
|
|
|
|
music: data.music_playing
|
|
? {
|
|
isPlaying: data.music_playing,
|
|
track: data.music_track,
|
|
artist: data.music_artist,
|
|
album: data.music_album,
|
|
platform: data.music_platform || "spotify",
|
|
progress: data.music_progress,
|
|
albumArt: data.music_album_art,
|
|
spotifyUrl: data.music_track
|
|
? `https://open.spotify.com/search/${encodeURIComponent(data.music_track + " " + data.music_artist)}`
|
|
: null,
|
|
}
|
|
: null,
|
|
|
|
watching: data.watching_title
|
|
? {
|
|
title: data.watching_title,
|
|
platform: data.watching_platform || "youtube",
|
|
type: data.watching_type || "video",
|
|
}
|
|
: null,
|
|
|
|
gaming: data.gaming_game
|
|
? {
|
|
game: data.gaming_game,
|
|
platform: data.gaming_platform || "steam",
|
|
status: data.gaming_status || "playing",
|
|
}
|
|
: null,
|
|
|
|
status: data.status_mood
|
|
? {
|
|
mood: data.status_mood,
|
|
customMessage: data.status_message,
|
|
}
|
|
: null,
|
|
},
|
|
{
|
|
headers: {
|
|
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
|
|
Pragma: "no-cache",
|
|
},
|
|
},
|
|
);
|
|
} catch (error) {
|
|
// Only log non-table-missing errors
|
|
if (error instanceof Error && !error.message.includes('does not exist')) {
|
|
console.error("Error fetching activity status:", error);
|
|
}
|
|
|
|
// Return empty state on error (graceful degradation)
|
|
return NextResponse.json(
|
|
{
|
|
activity: null,
|
|
music: null,
|
|
watching: null,
|
|
gaming: null,
|
|
status: null,
|
|
},
|
|
{
|
|
status: 200, // Return 200 to prevent frontend errors
|
|
headers: {
|
|
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
|
|
},
|
|
},
|
|
);
|
|
}
|
|
}
|