This is a personal portfolio website built to showcase my skills, experience, education, and projects as a Software Engineer. The website features a modern, clean design with smooth animations, da[โฆ]
| Technology | Version | Purpose |
|---|---|---|
| React | 18.3.1 | UI library for building components |
| TypeScript | 5.0+ | Type-safe JavaScript |
| Vite | Latest | Fast build tool and dev server |
| Tailwind CSS | 3.4+ | Utility-first CSS framework |
| Library | Purpose |
|---|---|
| shadcn/ui | Pre-built accessible UI components |
| Radix UI | Unstyled accessible primitives |
| Lucide React | Modern icon library |
| Embla Carousel | Touch-friendly carousel component |
| Package | Purpose |
|---|---|
| React Router DOM | Client-side routing |
| React Hook Form | Form state management |
| TanStack Query | Data fetching and caching |
| next-themes | Theme management (dark/light) |
| Sonner | Toast notifications |
| Zod | Schema validation |
| Tool | Purpose |
|---|---|
| ESLint | Code linting |
| PostCSS | CSS processing |
| Autoprefixer | Browser compatibility |
| Class Variance Authority | Component variant management |
| clsx & tailwind-merge | Conditional class name handling |
src/
โโโ assets/ # Static assets (images, icons)
โ โโโ profile-photo.jpeg # Profile picture
โ โโโ architecture-flink.png
โ
โโโ components/ # React components
โ โโโ ui/ # shadcn/ui components
โ โ โโโ button.tsx
โ โ โโโ card.tsx
โ โ โโโ input.tsx
โ โ โโโ carousel.tsx
โ โ โโโ ... (40+ components)
โ โ
โ โโโ About.tsx # About section component
โ โโโ Skills.tsx # Skills section component
โ โโโ Education.tsx # Education section component
โ โโโ Experience.tsx # Experience section component
โ โโโ Projects.tsx # Projects carousel component
โ โโโ Contact.tsx # Contact form component
โ โโโ Hero.tsx # Hero section with animations
โ โโโ Navigation.tsx # Header navigation
โ โโโ Footer.tsx # Footer component
โ โโโ LoadingScreen.tsx # Initial loading animation
โ โโโ ProjectDocumentation.tsx # Project detail content
โ
โโโ data/ # Data files
โ โโโ flink-docs.tsx # Flink project documentation
โ โโโ founderconnect-docs.tsx
โ โโโ musical-portfolio-docs.tsx
โ
โโโ hooks/ # Custom React hooks
โ โโโ use-mobile.tsx # Mobile detection hook
โ โโโ use-toast.ts # Toast notification hook
โ
โโโ lib/ # Utility functions
โ โโโ utils.ts # Helper functions (cn, etc.)
โ
โโโ pages/ # Page components
โ โโโ Index.tsx # Home page
โ โโโ AllProjects.tsx # Projects list page
โ โโโ ProjectDetail.tsx # Individual project page
โ โโโ NotFound.tsx # 404 error page
โ
โโโ App.tsx # Main app component with routing
โโโ main.tsx # Application entry point
โโโ index.css # Global styles & design system
โโโ vite-env.d.ts # TypeScript declarations
public/
โโโ Sanidhya_Dash_Resume.pdf # Resume download
โโโ robots.txt # SEO configuration
Configuration Files:
โโโ tailwind.config.ts # Tailwind configuration
โโโ vite.config.ts # Vite build configuration
โโโ tsconfig.json # TypeScript configuration
โโโ eslint.config.js # ESLint rules
โโโ vercel.json # Deployment configuration
App
โโโ ThemeProvider (Dark/Light Mode)
โโโ QueryClientProvider (Data Fetching)
โโโ TooltipProvider (Tooltips)
โโโ BrowserRouter (Routing)
โโโ LoadingScreen (Session-based)
โโโ Routes
โโโ Index (Home Page)
โ โโโ Navigation
โ โโโ Hero
โ โโโ About
โ โโโ Skills
โ โโโ Education
โ โโโ Experience
โ โโโ Projects
โ โโโ Contact
โ โโโ Footer
โ
โโโ AllProjects
โ โโโ Navigation
โ โโโ Project Grid
โ โโโ Footer
โ
โโโ ProjectDetail
โ โโโ Navigation
โ โโโ Project Header
โ โโโ ProjectDocumentation
โ โโโ Footer
โ
โโโ NotFound
The design system uses HSL color values for better theme management and manipulation.
--primary: 190 95% 55% /* Cyan Blue - #00D9FF */
--secondary: 260 60% 55% /* Purple - #7D5FFF */
--accent: 290 70% 60% /* Magenta - #E066FF */
--background: 0 0% 100% /* White */
--foreground: 222.2 84% 4.9% /* Near Black */
--muted: 210 40% 96.1% /* Light Gray */
--border: 214.3 31.8% 91.4% /* Border Gray */
--primary: 190 95% 55% /* Cyan Blue - Same */
--secondary: 260 60% 55% /* Purple - Same */
--accent: 290 70% 60% /* Magenta - Same */
--background: 220 25% 6% /* Dark Blue-Gray */
--foreground: 210 40% 98% /* Off White */
--muted: 220 15% 20% /* Dark Gray */
--border: 220 15% 20% /* Dark Border */
/* Primary Gradient: Cyan to Purple */
--gradient-primary: linear-gradient(135deg,
hsl(190 95% 55%),
hsl(260 60% 55%)
);
/* Secondary Gradient: Purple to Magenta */
--gradient-secondary: linear-gradient(135deg,
hsl(260 60% 55%),
hsl(290 70% 60%)
);
/* Subtle Accent Gradient */
--gradient-accent: linear-gradient(135deg,
hsl(190 95% 55% / 0.1),
hsl(260 60% 55% / 0.1)
);
--glow-primary: 0 0 40px hsl(190 95% 55% / 0.3);
--glow-secondary: 0 0 40px hsl(260 60% 55% / 0.3);
--radius: 0.75rem /* 12px base radius */
lg: var(--radius)
md: calc(var(--radius) - 2px)
sm: calc(var(--radius) - 4px)
Following Tailwindโs default spacing scale (4px base unit):
p-4 = 1rem (16px)p-6 = 1.5rem (24px)p-8 = 2rem (32px)::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
background: hsl(var(--background));
}
::-webkit-scrollbar-thumb {
background: hsl(var(--primary) / 0.3);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: hsl(var(--primary) / 0.5);
}
Hero.tsxPurpose: Landing section with animated introduction
Features:
State Management:
text: Current typed textisDeleting: Typing direction flagloopNum: Loop countertypingSpeed: Dynamic typing speed (150ms normal, 50ms deleting)Key Animations:
animate-float: Continuous up/down motion (6s loop)animate-fade-in: Fade in with translateY (0.6s)animate-pulse: Pulsing opacity (2s loop)animate-bounce: Scroll indicator bounceAbout.tsxPurpose: Personal introduction with highlight cards
Features:
Intersection Observer:
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
},
{ threshold: 0.1 }
);
Skills.tsxPurpose: Showcase technical skills by category
Data Structure:
interface Skill {
name: string;
icon: string; // CDN URL
}
interface SkillCategory {
category: string;
skills: Skill[];
}
Categories:
Features:
Education.tsx & Experience.tsxPurpose: Display academic and professional journey
Common Features:
Education Data Points:
Experience Data Points:
Projects.tsxPurpose: Showcase featured projects in carousel
Carousel Configuration:
opts=
Project Data Structure:
interface Project {
id: string;
title: string;
description: string;
tags: string[];
gradient: string;
codeLink: string;
liveLink: string;
}
Features:
Contact.tsxPurpose: Contact form and information
Form Handling:
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Creates mailto link with form data
window.location.href = `mailto:sanidhyadash32@gmail.com?subject=${subject}&body=${body}`;
toast.success("Opening your email client...");
};
Contact Info:
Navigation.tsxPurpose: Site-wide navigation with theme toggle
Features:
Scroll Handler:
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 50);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
LoadingScreen.tsxPurpose: Initial loading animation
Session Management:
// Only show once per session
const hasSeenLoading = sessionStorage.getItem('hasSeenLoading');
if (hasSeenLoading) {
setIsLoading(false);
}
Animation Timeline:
<Routes>
<Route path="/" element={<Index />} />
<Route path="/projects" element={<AllProjects />} />
<Route path="/projects/:projectId" element={<ProjectDetail />} />
<Route path="*" element={<NotFound />} />
</Routes>
Index.tsx (Home Page)URL: /
Sections (in order):
AllProjects.tsxURL: /projects
Features:
ProjectDetail.tsxURL: /projects/:projectId
Supported IDs:
flinkfounderconnectmusical-artist-portfolioFeatures:
Documentation Loading:
const getDocumentation = () => {
switch (projectId) {
case "flink":
return getFlinkDocumentation();
case "founderconnect":
return getFounderConnectDocumentation();
case "musical-artist-portfolio":
return getMusicalPortfolioDocumentation();
default:
return null;
}
};
NotFound.tsxURL: Any invalid route
Features:
@keyframes fade-in {
0% { opacity: 0; transform: translateY(20px); }
100% { opacity: 1; transform: translateY(0); }
}
@keyframes fade-in-left {
0% { opacity: 0; transform: translateX(-20px); }
100% { opacity: 1; transform: translateX(0); }
}
@keyframes fade-in-right {
0% { opacity: 0; transform: translateX(20px); }
100% { opacity: 1; transform: translateX(0); }
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-20px); }
}
/* Duration: 6s ease-in-out infinite */
@keyframes glow {
0%, 100% { box-shadow: 0 0 20px hsl(190 95% 55% / 0.3); }
50% { box-shadow: 0 0 40px hsl(190 95% 55% / 0.6); }
}
/* Duration: 2s ease-in-out infinite */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Duration: 3s linear infinite */
@keyframes accordion-down {
from { height: 0; }
to { height: var(--radix-accordion-content-height); }
}
@keyframes accordion-up {
from { height: var(--radix-accordion-content-height); }
to { height: 0; }
}
/* Duration: 0.2s ease-out */
--transition-smooth: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
Card Hover:
.card:hover {
transform: scale(1.02);
border-color: hsl(var(--primary) / 0.6);
box-shadow: 0 0 30px hsl(190 95% 55% / 0.2);
}
Button Hover:
.button:hover {
box-shadow: 0 0 20px hsl(190 95% 55% / 0.3);
}
Icon Hover:
.icon:hover {
transform: scale(1.1);
color: hsl(var(--primary));
}
Used in multiple components for sequential appearance:
// Use raw string to prevent Jekyll template parsing
// style={ { animationDelay: `${index * 100}ms`, transitionDelay: `${index * 150}ms` } }
// In actual React component, template literals work correctly
Correct implementation in component files (lines 755-760 reference):
Apply template literal syntax directly in .tsx files:
style={Object.assign({},
{ animationDelay: `${index * 100}ms` },
{ transitionDelay: `${index * 150}ms` }
)}
Components use Intersection Observer for scroll-triggered animations:
const [isVisible, setIsVisible] = useState(false);
const sectionRef = useRef<HTMLElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
},
{ threshold: 0.1 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
// Apply based on isVisible state
className={`${ isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"}`}
git clone https://github.com/SANIDHYADASH/My-Portfolio.git
npm install
# or
yarn install
# or
pnpm install
npm run dev
# or
yarn dev
# or
pnpm dev
The application will be available at http://localhost:5173
# Start development server with hot reload
npm run dev
# Build for production
npm run build
# Preview production build locally
npm run preview
# Run linter
npm run lint
# Type check
npm run type-check
This project doesnโt require environment variables for basic functionality. However, if you want to add analytics or other integrations:
Create .env file in root:
VITE_ANALYTICS_ID=your_analytics_id
VITE_API_URL=your_api_url
Access in code:
const analyticsId = import.meta.env.VITE_ANALYTICS_ID;
npm install -g vercel
vercel
npm run builddist[[redirects]] from = โ/*โ to = โ/index.htmlโ status = 200
### Deploy to GitHub Pages
1. **Update vite.config.ts**:
```typescript
export default defineConfig({
base: '/your-repo-name/',
// ... rest of config
});
npm install -D gh-pages
{
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
}
}
npm run deploy
Type: CNAME
Name: www
Value: your-site.vercel.app
npm run build
Check dist/ folder size and analyze:
npx vite-bundle-visualizer
Lighthouse Scores (Target):
| Browser | Version |
|---|---|
| Chrome | Last 2 versions |
| Firefox | Last 2 versions |
| Safari | Last 2 versions |
| Edge | Last 2 versions |
| Opera | Last 2 versions |
| Browser | Version |
|---|---|
| Chrome Android | Last 2 versions |
| Safari iOS | Last 2 versions |
| Samsung Internet | Last 2 versions |
Key features used:
Vite automatically includes necessary polyfills for:
This is a personal portfolio project, but suggestions and bug reports are welcome!
git checkout -b feature/AmazingFeature
git commit -m 'Add some AmazingFeature'
git push origin feature/AmazingFeature
type(scope): subject
body
footer
Types: feat, fix, docs, style, refactor, test, chore
Example:
feat(projects): add filter functionality
- Add filter buttons for technologies
- Implement filter logic
- Update UI to show filtered results
Closes #123
This project is open source and available under the MIT License.
MIT License
Copyright (c) 2024 Sanidhya Dash
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Sanidhya Dash