Det9999 commited on
Commit
71b697b
·
verified ·
1 Parent(s): 3c38ef0

Upload pages/index.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. pages/index.js +155 -0
pages/index.js ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from 'react';
2
+ import { Settings, LogOut, Play, Loader2 } from 'lucide-react';
3
+ import ConfigModal from '@/components/ConfigModal';
4
+ import ChatInterface from '@/components/ChatInterface';
5
+ import SpotifyDashboard from '@/components/SpotifyDashboard';
6
+ import axios from 'axios';
7
+
8
+ export default function Home() {
9
+ const [config, setConfig] = useState(null);
10
+ const [showConfig, setShowConfig] = useState(false);
11
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
12
+ const [accessToken, setAccessToken] = useState(null);
13
+
14
+ // Spotify Data States
15
+ const [userData, setUserData] = useState(null);
16
+ const [topTracks, setTopTracks] = useState(null);
17
+ const [topArtists, setTopArtists] = useState(null);
18
+ const [isLoadingData, setIsLoadingData] = useState(false);
19
+
20
+ // Chat States
21
+ const [messages, setMessages] = useState([]);
22
+ const [isChatLoading, setIsChatLoading] = useState(false);
23
+
24
+ // Initialize config from localStorage
25
+ useEffect(() => {
26
+ const savedConfig = localStorage.getItem('spotify_ai_config');
27
+ if (savedConfig) {
28
+ setConfig(JSON.parse(savedConfig));
29
+ }
30
+
31
+ // Check for OAuth code in URL
32
+ const urlParams = new URLSearchParams(window.location.search);
33
+ const code = urlParams.get('code');
34
+ if (code) {
35
+ handleCallback(code);
36
+ // Clean URL
37
+ window.history.replaceState({}, document.title, window.location.pathname);
38
+ }
39
+ }, []);
40
+
41
+ const handleSaveConfig = (newConfig) => {
42
+ setConfig(newConfig);
43
+ localStorage.setItem('spotify_ai_config', JSON.stringify(newConfig));
44
+ };
45
+
46
+ const handleLogin = async () => {
47
+ if (!config?.spotifyId) {
48
+ setShowConfig(true);
49
+ return;
50
+ }
51
+ try {
52
+ const redirectUri = `${window.location.origin}/api/auth/callback`;
53
+ const res = await axios.post('/api/auth/login', {
54
+ clientId: config.spotifyId,
55
+ redirectUri
56
+ });
57
+ window.location.href = res.data.url;
58
+ } catch (error) {
59
+ console.error('Login error:', error);
60
+ alert('Failed to initiate login');
61
+ }
62
+ };
63
+
64
+ const handleCallback = async (code) => {
65
+ try {
66
+ const savedConfig = JSON.parse(localStorage.getItem('spotify_ai_config'));
67
+ if (!savedConfig) return;
68
+
69
+ const redirectUri = `${window.location.origin}/api/auth/callback`;
70
+ const res = await axios.post('/api/auth/callback', {
71
+ code,
72
+ clientId: savedConfig.spotifyId,
73
+ clientSecret: savedConfig.spotifySecret,
74
+ redirectUri
75
+ });
76
+
77
+ setAccessToken(res.data.access_token);
78
+ setIsAuthenticated(true);
79
+ fetchSpotifyData(res.data.access_token);
80
+ } catch (error) {
81
+ console.error('Callback error:', error);
82
+ alert('Authentication failed. Please check your credentials.');
83
+ }
84
+ };
85
+
86
+ const fetchSpotifyData = async (token) => {
87
+ setIsLoadingData(true);
88
+ try {
89
+ const [profileRes, tracksRes, artistsRes] = await Promise.all([
90
+ axios.get(`/api/spotify/data?type=profile&accessToken=${token}`),
91
+ axios.get(`/api/spotify/data?type=tracks&accessToken=${token}`),
92
+ axios.get(`/api/spotify/data?type=artists&accessToken=${token}`)
93
+ ]);
94
+
95
+ setUserData(profileRes.data);
96
+ setTopTracks(tracksRes.data.items);
97
+ setTopArtists(artistsRes.data.items);
98
+ } catch (error) {
99
+ console.error('Data fetch error:', error);
100
+ // Only alert if it's not a 401 (handled elsewhere)
101
+ if (error.response?.status !== 401) {
102
+ alert('Failed to load profile data');
103
+ }
104
+ } finally {
105
+ setIsLoadingData(false);
106
+ }
107
+ };
108
+
109
+ const handleLogout = () => {
110
+ setAccessToken(null);
111
+ setIsAuthenticated(false);
112
+ setUserData(null);
113
+ setTopTracks(null);
114
+ setTopArtists(null);
115
+ setMessages([]);
116
+ };
117
+
118
+ const handleSendMessage = async (content) => {
119
+ if (!config?.aiApiKey) {
120
+ setShowConfig(true);
121
+ alert('Please configure your AI API Key first.');
122
+ return;
123
+ }
124
+
125
+ const newMessage = { role: 'user', content };
126
+ setMessages(prev => [...prev, newMessage]);
127
+ setIsChatLoading(true);
128
+
129
+ try {
130
+ const res = await axios.post('/api/ai/chat', {
131
+ messages: [...messages, newMessage],
132
+ spotifyContext: { profile: userData, topTracks, topArtists },
133
+ apiKey: config.aiApiKey,
134
+ provider: config.aiProvider,
135
+ model: config.aiModel
136
+ });
137
+
138
+ const aiMessage = { role: 'assistant', content: res.data.content };
139
+ setMessages(prev => [...prev, aiMessage]);
140
+ } catch (error) {
141
+ console.error('Chat error:', error);
142
+ const errorMsg = {
143
+ role: 'assistant',
144
+ content: `Sorry, I encountered an error: ${error.response?.data?.details || error.message}`
145
+ };
146
+ setMessages(prev => [...prev, errorMsg]);
147
+ } finally {
148
+ setIsChatLoading(false);
149
+ }
150
+ };
151
+
152
+ return (
153
+ <div className="min-h-screen flex flex-col">
154
+ {/* Main Content Grid */}
155
+ <div className="flex-1 grid grid-cols-1 lg:grid-cols-12 gap-6 h-[calc(100vh-80px)]">