back. WiP

graph package (reactflow), updates. assets, some of the SEO. started with some basic components, login, navbar, etc.
This commit is contained in:
2024-12-28 12:12:17 -07:00
parent cc682254df
commit c1bc6177d8
36 changed files with 5423 additions and 18018 deletions

View File

@@ -0,0 +1,6 @@
.graph_wrapper {
display: flex;
position: inherit;
width: 100%;
height: 80vh;
}

47
src/pages/Graph/index.jsx Normal file
View File

@@ -0,0 +1,47 @@
import React, { useCallback } from 'react';
import {
ReactFlow,
Controls,
Background,
useNodesState,
useEdgesState,
addEdge,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import styles from './Graph.module.css';
// const initialNodes = [];
const initialNodes = [
{ id: '1', position: { x: 0, y: 0 }, data: { label: '1' } },
{ id: '2', position: { x: 0, y: 100 }, data: { label: '2' } },
];
// const initialEdges = [];
const initialEdges = [
{ id: 'e1-2', source: '1', target: '2' }
];
const Graph = () => {
const [playlistNodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [linkEdges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback((params) => {
setEdges((eds) => addEdge(params, eds));
}, [setEdges]);
return (
<div className={styles.graph_wrapper}>
<ReactFlow
nodes={playlistNodes}
edges={linkEdges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
>
<Controls />
<Background variant='dots' gap={36} size={3} />
</ReactFlow>
</div>
)
}
export default Graph;

View File

@@ -0,0 +1,27 @@
.app_header {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
}
.app_logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.app_logo {
animation: App-logo-spin infinite 20s linear;
}
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,28 @@
import React, { useEffect } from "react"
import { useSearchParams } from "react-router-dom";
import styles from "./Landing.module.css"
import logo from '../../assets/icons/logo.svg';
import { showSuccessToastNotification } from "../../components/ToastNotification";
const Landing = () => {
// eslint-disable-next-line no-unused-vars
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
if (searchParams.get("login") === "success") {
showSuccessToastNotification("Logged in!");
}
}, [searchParams]);
return (
<header className={styles.app_header}>
<img src={logo} className={styles.app_logo} alt="logo" />
<h1>Organize your Spotify playlists as a graph.</h1>
<h5>Features:</h5>
<ul>
<li>blah 1</li>
</ul>
</header>
)
}
export default Landing

View File

@@ -0,0 +1,6 @@
.login_wrapper {
display: flex;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
}

18
src/pages/Login/index.jsx Normal file
View File

@@ -0,0 +1,18 @@
import React, { useEffect } from 'react';
import styles from './Login.module.css';
// auth through backend
const Login = () => {
useEffect(() => {
const timeoutID = setTimeout(() => {
window.open(process.env.REACT_APP_API_BASE_URL + "/api/auth/login", "_self")
}, 1000);
return () => clearTimeout(timeoutID);
}, []);
return (
<div className={styles.login_wrapper}>Redirecting to Spotify...</div>
)
}
export default Login;

View File

@@ -0,0 +1,17 @@
import React, { useEffect } from 'react';
import styles from "./PageNotFound.module.css";
import { showWarnToastNotification } from '../../components/ToastNotification';
const PageNotFound = () => {
useEffect(() => {
showWarnToastNotification("Oops!")
}, []);
return (
<div className={styles.pnf_wrapper}>
PageNotFound
</div>
)
}
export default PageNotFound