pleaseeeeee

This commit is contained in:
Unknown 2024-12-24 00:20:15 -07:00 committed by End
parent 6763bd7c6f
commit 40605d69ae
No known key found for this signature in database
19 changed files with 234 additions and 17145 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

17
deploy.ps1 Normal file
View file

@ -0,0 +1,17 @@
# Step 1: Install Dependencies
Write-Output "Installing dependencies..."
npm install
# Step 2: Build Frontend
Write-Output "Building the React project..."
npm run build
# Step 3: Deploy Frontend to Cloudflare Pages
Write-Output "Deploying frontend to Cloudflare Pages..."
wrangler pages deploy ./build --project-name personal-site
# Step 4: Deploy Backend to Cloudflare Workers
Write-Output "Deploying backend worker..."
wrangler deploy spotify-worker.js --name spotify-worker
Write-Output "✅ Deployment complete! Frontend and backend are live."

17141
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,22 @@
"private": true,
"dependencies": {
"cra-template": "1.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-scripts": "5.0.1"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"@babel/plugin-transform-private-methods": "^7.25.9",
"@babel/plugin-transform-numeric-separator": "^7.25.9",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
"@babel/plugin-transform-optional-chaining": "^7.25.9",
"@eslint/eslintrc": "^1.4.1",
"@eslint/js": "^8.57.1",
"@jridgewell/sourcemap-codec": "^1.5.0",
"@rollup/plugin-terser": "7.0.2",
"eslint": "^8.57.1",
"rimraf": "^4.4.1",
"glob": "^9.3.5",
"svgo": "^2.8.0"
},
"scripts": {
"start": "react-scripts start",

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

View file

@ -7,6 +7,7 @@
<link rel="stylesheet" href="pages/style.css">
</head>
<body>
<img src="/logo.png" alt="Logo" style="width: 100px; height: auto;">
<div id="root"></div>
<script src="/scripts/theme-toggle.js"></script>
<script src="/scripts/spotify.js"></script>

BIN
public/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -19,6 +19,7 @@
});
</script>
<main>
<img src="/logo.png" alt="Logo" style="width: 100px; height: auto;">
<h1>My GitHub Projects</h1>
<ul id="repo-list"></ul>
</main>

View file

@ -0,0 +1,23 @@
@keyframes rollingCode {
0% { transform: translateY(0); opacity: 1; }
100% { transform: translateY(100vh); opacity: 0; }
}
body {
margin: 0;
overflow: hidden;
background: black;
color: limegreen;
font-family: monospace;
font-size: 1rem;
}
.code-line {
position: absolute;
top: -10%;
width: 100%;
white-space: nowrap;
overflow: hidden;
animation: rollingCode 5s linear infinite;
}

View file

@ -0,0 +1,10 @@
fetch('/github-repos')
.then(response => response.json())
.then(data => {
const repoList = document.getElementById('repo-list');
data.forEach(repo => {
const listItem = document.createElement('li');
listItem.innerHTML = `<h3>${repo.name}</h3><p>${repo.readme}</p>`;
repoList.appendChild(listItem);
});
});

10
public/scripts/spotify.js Normal file
View file

@ -0,0 +1,10 @@
fetch('/spotify-data')
.then(response => response.json())
.then(data => {
const spotifyList = document.getElementById('spotify-list');
data.items.forEach(track => {
const listItem = document.createElement('li');
listItem.textContent = `${track.name} by ${track.artists.map(artist => artist.name).join(', ')}`;
spotifyList.appendChild(listItem);
});
});

View file

@ -0,0 +1,13 @@
const colorPicker = document.getElementById('theme-color-picker'); // Get the color picker element
// set intial color
const currentColor = localStorage.getItem('theme-color'); || '#3f10ad';
document.documentElement.style.setProperty('--primary-color', currentColor);
colorPicker.value = currentColor;
// update theme color and sae in local storage
colorPicker.addEventListener('input', (event) => {
const newColor = event.target.value;
document.documentElement.style.setProperty('--primary-color', newColor);
localStorage.setItem('theme-color', newColor);
})

View file

@ -87,4 +87,38 @@ app.get('/github-repos', async (req, res) => {
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
});
app.get('/spotify-data', async (req, res) => {
if (!access_token) {
return res.status(401).json({ error: 'User not authenticated. Please login first.' });
}
try {
const fetch = (await import('node-fetch')).default;
// Fetch user's top tracks
const tracksResponse = await fetch('https://api.spotify.com/v1/me/top/tracks?limit=10', {
headers: { Authorization: `Bearer ${access_token}` }
});
const topTracks = await tracksResponse.json();
// Fetch user's playlists
const playlistsResponse = await fetch('https://api.spotify.com/v1/me/playlists?limit=5', {
headers: { Authorization: `Bearer ${access_token}` }
});
const playlists = await playlistsResponse.json();
res.json({
topTracks: topTracks.items.map(track => ({
name: track.name,
artist: track.artists.map(artist => artist.name).join(', ')
})),
playlists: playlists.items.map(playlist => ({
name: playlist.name,
url: playlist.external_urls.spotify
}))
});
} catch (error) {
console.error('Error fetching Spotify data:', error);
res.status(500).json({ error: 'Failed to fetch Spotify data' });
}
});

View file

@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import GithubRepos from './GithubRepos';
test('renders GithubRepos component', () => {
render(<GithubRepos />);
const linkElement = screen.getByText(/Github Repositories/i);
expect(linkElement).toBeInTheDocument();
});

View file

@ -0,0 +1,62 @@
.loading-container {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-background {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
opacity: 0.2;
z-index: -1;
}
.code-char {
color: #00ff00;
font-family: 'Courier New', Courier, monospace;
font-size: 14px;
animation: scroll 10s linear infinite;
}
.code-char:hover {
background-color: rgba(255, 255, 255, 0.1);
}
@keyframes scroll {
0% { transform: translateY(100%); }
100% { transform: translateY(-100%); }
}
.loading-blocks {
display: flex;
gap: 10px;
}
.block {
width: 20px;
height: 20px;
background-color: var(--primary-color);
animation: block-loading 1s infinite;
}
.block:nth-child(1) { animation-delay: 0s; }
.block:nth-child(2) { animation-delay: 0.2s; }
.block:nth-child(3) { animation-delay: 0.4s; }
.block:nth-child(4) { animation-delay: 0.6s; }
.block:nth-child(5) { animation-delay: 0.8s; }
@keyframes block-loading {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.5); }
}

View file

@ -0,0 +1,34 @@
import React, { useEffect, useState } from 'react';
import './LoadingAnimation.css';
const generateRandomCode = () => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+[]{}|;:,.<>?';
return Array.from({ length: 100 }, () => characters.charAt(Math.floor(Math.random() * characters.length)));
};
const LoadingAnimation = () => {
const [codeLines, setCodeLines] = useState([]);
useEffect(() => {
setCodeLines(generateRandomCode());
}, []);
return (
<div className="loading-container">
<div className="loading-background">
{codeLines.map((char, index) => (
<span key={index} className="code-char">{char}</span>
))}
</div>
<div className="loading-blocks">
<div className="block"></div>
<div className="block"></div>
<div className="block"></div>
<div className="block"></div>
<div className="block"></div>
</div>
</div>
);
};
export default LoadingAnimation;

View file

@ -3,3 +3,4 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
ks