diff --git a/src/App.tsx b/src/App.tsx
index 176b4ac..f326182 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,8 +1,9 @@
import 'reactflow/dist/style.css'
import './custom_node.css'
-import Header from './Header.tsx'
-import Flow from './Flow.tsx'
-import Search from './Search.tsx'
+import Header from './Header'
+import Flow from './Flow'
+import Search from './Search'
+import React from 'react'
const App = () => {
return (
diff --git a/src/CustomNode.tsx b/src/CustomNode.tsx
index 2d44007..eb2e294 100644
--- a/src/CustomNode.tsx
+++ b/src/CustomNode.tsx
@@ -1,3 +1,4 @@
+import React from 'react'
import { Handle, Position } from 'reactflow'
type NodeData = {
diff --git a/src/Flow.tsx b/src/Flow.tsx
index d8c2114..c23346d 100644
--- a/src/Flow.tsx
+++ b/src/Flow.tsx
@@ -13,6 +13,7 @@ import 'reactflow/dist/style.css'
import './custom_node.css'
import CustomNode from './CustomNode'
import { FlowContext } from './context/FlowContext'
+import React from 'react'
const Flow = () => {
const { nodes, setNodes, edges, setEdges } = useContext(FlowContext)
diff --git a/src/Header.tsx b/src/Header.tsx
index 8be34af..5f67bca 100644
--- a/src/Header.tsx
+++ b/src/Header.tsx
@@ -1,3 +1,5 @@
+import React from "react"
+
function Header() {
return (
diff --git a/src/Search.tsx b/src/Search.tsx
index f11b49b..d71ff9f 100644
--- a/src/Search.tsx
+++ b/src/Search.tsx
@@ -1,158 +1,147 @@
import React from 'react';
-import SearchList from './SearchList.tsx'
-import { useContext, useState } from 'react'
+import SearchList from './SearchList'
+import {useContext, useState} from 'react'
import axios from 'axios'
-import { SpotifyContext } from './context/SpotifyContext.tsx'
-import { FlowContext } from './context/FlowContext.tsx'
-import { saveAs } from 'file-saver';
+import {SpotifyContext} from './context/SpotifyContext'
+import {FlowContext} from './context/FlowContext'
+import {saveAs} from 'file-saver';
const CLIENT_ID = '0350c90137454dc5a748549664e5ba75'
const REDIRECT_URI = window.location.href
-console.log(REDIRECT_URI);
const AUTH_ENDPOINT = 'https://accounts.spotify.com/authorize'
const RESPONSE_TYPE = 'token'
function Search() {
- const { token, logout } = useContext(SpotifyContext)
- const { nodes, setNodes, edges, setEdges } = useContext(FlowContext)
-
- const [searchKey, setSearchKey] = useState('')
- const [tracks, setTracks] = useState([])
-
- const getTrackFeatures = async (token, trackId) => {
- const response = await axios.get(`https://api.spotify.com/v1/audio-features/${trackId}`, {
- headers: {
- Authorization: `Bearer ${token}`,
- }
- });
-
- return response.data;
- };
-
- const searchTracks = async (e) => {
- e.preventDefault()
- const { data } = await axios.get('https://api.spotify.com/v1/search', {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- params: {
- q: searchKey,
- type: 'track',
- },
- })
-
- const trackItems = data.tracks.items;
-
- const trackFeaturesPromises = trackItems.map(async (item) => {
- const features = await getTrackFeatures(token, item.id);
- return {
- track: item,
- features: features
- };
- });
-
- const trackFeatures = await Promise.all(trackFeaturesPromises);
-
- setTracks(trackFeatures)
- }
-
- const handleExport = (e) => {
- const data = {
- nodes: nodes,
- edges: edges
+ const {token, logout} = useContext(SpotifyContext)
+ const {nodes, setNodes, edges, setEdges} = useContext(FlowContext)
+
+ const [searchKey, setSearchKey] = useState('')
+ const [tracks, setTracks] = useState([])
+
+ async function getTrackFeatures(token, track_id) {
+ const response = await axios.get(`https://api.spotify.com/v1/audio-features/${track_id}`, {
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ });
+ return response.data;
};
- const json = JSON.stringify(data);
- const blob = new Blob([json], { type: 'application/json' });
-
- saveAs(blob, 'track_lineage_export.json');
- }
-
- const fileInputRef = React.createRef();
-
- const handleImportButtonClick = () => {
- fileInputRef.current.click();
- };
-
- const handleImport = (event) => {
- const file = event.target.files[0];
- const reader = new FileReader();
-
- reader.onload = (e) => {
- try {
- const data = JSON.parse(e.target.result);
-
- if (data.nodes && data.edges) {
- setNodes(data.nodes);
- setEdges(data.edges);
- alert('Import successful!');
- } else {
- alert('Invalid file format. Please select a valid JSON file.');
+ async function searchTracks(e) {
+ e.preventDefault()
+ const {data} = await axios.get('https://api.spotify.com/v1/search', {
+ headers: {
+ Authorization: `Bearer ${token}`
+ },
+ params: {
+ q: searchKey,
+ type: 'track'
+ }
+ })
+
+ const trackItems = data.tracks.items;
+
+ const trackFeaturesPromises = trackItems.map(async (item) => {
+ const features = await getTrackFeatures(token, item.id);
+ return {track: item, features: features};
+ });
+ const trackFeatures = await Promise.all(trackFeaturesPromises);
+
+ setTracks(trackFeatures)
+ }
+
+ function handleExport(e) {
+ const data = {
+ nodes: nodes,
+ edges: edges
+ };
+ const json = JSON.stringify(data);
+ const blob = new Blob([json], {type: 'application/json'});
+ saveAs(blob, 'track_lineage_export.json');
+ }
+
+ const fileInputRef = React.createRef();
+
+ function handleImportButtonClick() {
+ fileInputRef.current.click();
+ }
+
+
+ function handleImport(event) {
+ const file = event.target.files[0];
+ const reader = new FileReader();
+
+ reader.onload = (e) => {
+ try {
+ const data = JSON.parse(e.target.result);
+
+ if (data.nodes && data.edges) {
+ setNodes(data.nodes);
+ setEdges(data.edges);
+ alert('Import successful!');
+ } else {
+ alert('Invalid file format. Please select a valid JSON file.');
+ }
+ } catch (error) {
+ alert('Error parsing JSON. Please check the file format.');
+ }
+ };
+
+ reader.readAsText(file);
+ }
+
+ return (
+
+ {
+ !token ? (
+
+ Login to Spotify
+
+ ) : (
+
+ )
}
- } catch (error) {
- alert('Error parsing JSON. Please check the file format.');
- }
- };
-
- reader.readAsText(file);
- };
-
- return (
-
- {!token ? (
-
- Login to Spotify
-
- ) : (
-
- )}
-
-
-
-
-
-
-
-
-
-
- )
+
+
+
+
+
+
+
+
+
+
+ )
}
export default Search
diff --git a/src/SearchList.tsx b/src/SearchList.tsx
index 0cd3194..98eb904 100644
--- a/src/SearchList.tsx
+++ b/src/SearchList.tsx
@@ -3,101 +3,116 @@ import { FormEvent } from 'react'
import { Node } from 'reactflow'
type Props = {
- nodes: Node[]
- setNodes: React.Dispatch
>
+ nodes: Node[];
+ setNodes: React.Dispatch < React.SetStateAction < Node[] >>;
}
function getKey(key) {
- switch(key) {
- case 0:
- return 'C';
- case 1:
- return 'C#/Db';
- case 2:
- return 'D';
- case 3:
- return 'D#/Eb';
- case 4:
- return 'E';
- case 5:
- return 'F';
- case 6:
- return 'F#/Gb';
- case 7:
- return 'G';
- case 8:
- return 'G#/Ab';
- case 9:
- return 'A';
- case 10:
- return 'A#/Bb';
- case 11:
- return 'B'
- default:
- return 'KEY';
- }
+ switch (key) {
+ case 0:
+ return 'C';
+ case 1:
+ return 'C#/Db';
+ case 2:
+ return 'D';
+ case 3:
+ return 'D#/Eb';
+ case 4:
+ return 'E';
+ case 5:
+ return 'F';
+ case 6:
+ return 'F#/Gb';
+ case 7:
+ return 'G';
+ case 8:
+ return 'G#/Ab';
+ case 9:
+ return 'A';
+ case 10:
+ return 'A#/Bb';
+ case 11:
+ return 'B'
+ default:
+ return 'KEY';
+ }
}
-function SearchList({ nodes, setNodes, tracks }: Props) {
- function onSubmit(track, event: FormEvent) {
- event.preventDefault()
- setNodes(
- nodes.concat({
- id: track.track.id,
- type: 'customNode',
- data: {
- title: track.track.name,
- artist: track.track.artists[0].name,
- bpm: track.features.tempo,
- key: getKey(track.features.key),
- image: track.track.album.images[0].url,
- },
- position: { x: 500, y: 25 },
- }),
- )
- }
+function SearchList({nodes, setNodes, tracks} : Props) {
+ function onSubmit(track, event : FormEvent < HTMLFormElement >) {
+ event.preventDefault()
+ setNodes(nodes.concat({
+ id: track.track.id,
+ type: 'customNode',
+ data: {
+ title: track.track.name,
+ artist: track.track.artists[0].name,
+ bpm: track.features.tempo,
+ key: getKey(track.features.key),
+ image: track.track.album.images[0].url
+ },
+ position: {
+ x: 500,
+ y: 25
+ }
+ }),)
+ }
- return (
-
- {tracks.map((track) => (
-
- ))}
-
- )
+ return (
+
+ {
+ tracks.map((track) => (
+
+ ))
+ }
+ )
}
export default SearchList