A modern, interactive portfolio website featuring real-time collaborative cursors
- π― GitHub Projects Showcase: Display your projects and contributions with glassmorphism card UI
- π Private Repository Support: Show your private repos on portfolio (GitHub Token required)
- ποΈ GUI Admin Panel: Manage repositories with web interface - settings apply to ALL visitors!
- π GitHub-based Storage: Admin settings saved to repository, shared across all users
- π Two Filter Modes: Blacklist (hide selected) or Whitelist (show only selected)
- π€ Auto-deploy: GitHub Actions automatically deploys changes
- π Real-time Multi-cursor System: See other visitors' cursors moving in real-time (circular pulse animation)
- π¨ Modern Glassmorphism Design: Clean, minimal aesthetic inspired by examples with blur effects
- π Two-View System: Switch between Home (profile) and Projects (repository list)
- π± Fully Responsive: Mobile-first design that adapts beautifully to all screen sizes
- π Blazing Fast: Built with Vite + React for optimal performance
- π Type-safe: Written in TypeScript with strict type checking
- β¨ Smooth Animations: Fade-in transitions, floating blobs, and gradient text effects
- React 19 - UI library
- TypeScript - Type safety
- Vite - Build tool
- Tailwind CSS 4 - Styling
- Framer Motion - Animations
- TanStack Query (React Query) - Server state management
- Supabase Realtime (Broadcast) - WebSocket-based real-time communication
- No database storage, pure socket communication
- Coordinates sent as percentages (%) for resolution independence
- Network-optimized with lodash throttle
- GitHub Actions - CI/CD
- GitHub Pages - Hosting
src/
βββ features/ # Feature-based modules
β βββ projects/ # GitHub projects showcase
β β βββ api.ts
β β βββ components/
β β β βββ ProjectCard.tsx
β β β βββ ProjectList.tsx
β β βββ hooks/
β β β βββ useProjects.ts
β β βββ types/
β βββ realtime/ # Real-time cursor system
β βββ components/
β β βββ CursorCanvas.tsx
β β βββ CursorPointer.tsx
β βββ hooks/
β β βββ useRealtimeCursors.ts
β βββ types/
βββ lib/ # Shared utilities
β βββ supabase.ts # Supabase client
β βββ query-client.ts
βββ pages/ # Page components
β βββ HomePage.tsx
βββ types/ # Global type definitions
β βββ index.ts
βββ main.tsx # Entry point
- Node.js 20+
- npm or yarn
# Clone the repository
git clone https://github.com/YOUR_USERNAME/03_portfolio_web.git
cd 03_portfolio_web
# Install dependencies
npm install
# Copy environment variables
cp .env.example .envCreate a .env file in the root directory:
# Supabase Configuration (for Realtime cursors)
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
# GitHub Configuration
VITE_GITHUB_USERNAME=your_github_username
VITE_GITHUB_TOKEN=ghp_xxxxx # Required: 'repo' permission for admin + private repos
VITE_GITHUB_REPO_NAME=03_portfolio_web
# Admin Panel
VITE_ADMIN_PASSWORD=admin123 # Default admin password
# Optional: Environment-based filtering (GUI admin is recommended)
VITE_GITHUB_SHOW_ONLY_REPOS=repo1,repo2 # Whitelist
VITE_GITHUB_HIDE_REPOS=test-repo # BlacklistGetting credentials:
- Supabase: supabase.com β Project Settings β API
- GitHub Token: Settings β Developer settings β Personal access tokens β Generate (select
reposcope)
# Start development server
npm run dev
# Open http://localhost:5173# Build for production
npm run build
# Preview production build
npm run previewThe project automatically deploys to GitHub Pages when you push to the main branch.
Setup GitHub Pages:
- Go to your repository settings
- Navigate to "Pages"
- Set source to "GitHub Actions"
- Add the following secrets to your repository:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYVITE_GITHUB_USERNAMEVITE_GITHUB_TOKEN(optional)
The cursor system uses Supabase Broadcast for real-time synchronization:
- Resolution Independence: Coordinates are sent as percentages (0-100%)
- Network Optimization: Throttled to 100ms using lodash
- No Database: Pure WebSocket communication without persistence
- User Identification: Random colors and IDs for each session
// Example: Cursor position broadcast
const handleMouseMove = throttle((e: MouseEvent) => {
const x = (e.clientX / window.innerWidth) * 100;
const y = (e.clientY / window.innerHeight) * 100;
channel.send({
type: 'broadcast',
event: 'cursor_move',
payload: { id: userId, x, y, userName, color }
});
}, 100);Projects are fetched directly from GitHub REST API and automatically categorized:
- My Projects: Repositories you own (not forked)
- Contributed Projects: Forked repositories or those you've contributed to
No separate backend server needed - everything runs client-side!
Control which repositories appear on your portfolio with GUI Admin Panel:
ποΈ Admin Panel Features:
- Access:
https://your-site-domain/admin.html(password:"your password") - GitHub-based Storage: Admin settings apply to ALL visitors (not per-browser)
- Two Modes: Blacklist (hide selected) or Whitelist (show only selected)
- Private Repos: Display your private repositories (GitHub Token required)
- Auto-deploy: Changes deploy automatically via GitHub Actions (~1-2 min)
π Quick Start:
# 1. Set environment variables
VITE_GITHUB_TOKEN=ghp_xxx # Required: 'repo' permission
VITE_GITHUB_REPO_NAME=your-repo-name
# 2. Access admin panel
https://your-site.github.io/admin.html
# 3. Login β Select repos β Save
# Changes apply to all visitors!π― Quick Start:
- Access admin panel:
https://your-site.github.io/admin.html - Login (default password:
admin123) - Check/uncheck repos to show/hide
- Click "πΎ μ€μ μ μ₯" (Save Settings)
- Go back to homepage to see changes!
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLintContributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
- Supabase for the real-time engine
- Vite for the blazing fast build tool
- TanStack Query for server state management
Made with β€οΈ by [Your Name]
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
}, ])