diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e59c411 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +## .NET +bin/ +obj/ +*.user +*.suo +*.userosscache +*.sln.docstates +.vs/ +.vscode/ + +## Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +## Visual Studio cache/options directory +.vs/ +.vscode/ + +## JetBrains Rider +.idea/ +*.sln.iml + +## User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +## ASP.NET Scaffolding +ScaffoldingReadMe.txt + +## Publish profiles +*.pubxml +*.azurePubxml + +## NuGet Packages +*.nupkg +*.snupkg +**/packages/* + +## Node.js (keeping for now, will remove after React cleanup) +node_modules/ +package-lock.json + +## OS files +.DS_Store +Thumbs.db diff --git a/migration.md b/migration.md new file mode 100644 index 0000000..17cd9d3 --- /dev/null +++ b/migration.md @@ -0,0 +1,766 @@ +# Blazor SSR Migration Plan + +## Project Overview +Migrating a React/TypeScript portfolio website to a **minimal, dependency-free** .NET Blazor application with static server-side rendering. + +**Current Stack:** +- React 18.2 + TypeScript +- Vite build tool +- Tailwind CSS (to be replaced with vanilla CSS) +- React Router DOM +- Headless UI components (Dialog/Tabs - to be replaced with vanilla HTML/CSS/JS) +- React Icons (to be replaced with SVG icons) +- Azure Static Web Apps hosting + +**Target Stack:** +- .NET 10 Blazor with Static SSR (no WebSockets/SignalR) +- C# Razor components (server-rendered only) +- **Vanilla CSS only** (no frameworks, no preprocessors) +- Blazor Router (built-in) +- **No external component libraries** +- **No icon dependencies** (inline SVG) +- Azure App Service or Azure Container Apps hosting + +**Migration Philosophy:** +- Zero external dependencies beyond .NET runtime +- Simple, maintainable vanilla CSS +- Static server-side rendering (no interactivity circuits) +- Modern CSS features (Grid, Flexbox, CSS Variables, Container Queries) +- Native HTML elements with custom styling +- **Zero JavaScript** - pure CSS solutions for all interactivity (checkbox hack, :target pseudo-class) + +--- + +## Phase 1: Project Setup + +### 1.1 .NET Project Initialization +- [ ] Install .NET 10 SDK +- [ ] Create new Blazor Web App project with SSR only: `dotnet new blazor -o src/BlazorApp -int None` + - Note: `-int None` disables interactivity (no SignalR/WebSockets) +- [ ] Verify project builds: `dotnet build` +- [ ] Review generated files: `Program.cs`, `App.razor`, `Components/_Imports.razor`, `appsettings.json` +- [ ] Confirm `Program.cs` does NOT include `AddInteractiveServerComponents()` or SignalR setup + +### 1.2 Solution Structure +- [ ] Create solution file: `dotnet new sln -n my-portfolio` +- [ ] Add project to solution: `dotnet sln add src/BlazorApp/BlazorApp.csproj` +- [ ] Configure project properties (nullable, implicit usings) +- [ ] Ensure render modes are set to static SSR only + +### 1.3 Git Configuration +- [ ] Update `.gitignore` for .NET (bin/, obj/, .vs/) +- [ ] Archive React project (move to `archive/react-version/` or create `pre-blazor-migration` tag) +- [ ] Commit initial Blazor project structure + +--- + +## Phase 2: CSS Architecture & Design System + +### 2.1 CSS Variables Setup +- [ ] Create `wwwroot/css/variables.css` with design tokens: + - Colors (black: #000, white: #fff, gray shades) + - Spacing scale (0.25rem, 0.5rem, 1rem, 1.5rem, 2rem, etc.) + - Typography (font-family: monospace, font-sizes, line-heights) + - Breakpoints (mobile-first: 640px, 768px, 1024px, 1280px) + - Z-index scale + - Border radius values + - Transition durations + +### 2.2 Base Styles +- [ ] Create `wwwroot/css/reset.css` with modern CSS reset +- [ ] Create `wwwroot/css/base.css`: + - Body styles (background: black, color: slate-50, font: monospace) + - Typography defaults + - Link styles + - Focus styles for accessibility + - Custom scrollbar styles + - Selection styles + +### 2.3 Layout Utilities +- [ ] Create `wwwroot/css/layout.css`: + - Container classes (max-width, centering) + - Flexbox utilities (flex, flex-col, items-center, justify-between, gap, etc.) + - Grid utilities (grid, grid-cols) + - Spacing utilities (padding, margin classes) + - Responsive utilities + +### 2.4 Component Styles +- [ ] Create `wwwroot/css/components.css`: + - Button styles (primary, secondary, hover, focus, disabled states) + - Input/textarea styles + - Card styles + - Navigation styles + - Footer styles + - Link styles +- [ ] Create `wwwroot/css/animations.css`: + - Fade-in animation + - Hover transitions + - Loading spinner animation + +### 2.5 Compile CSS +- [ ] Create `wwwroot/css/app.css` that imports all CSS files +- [ ] Reference in `index.html`: `` +- [ ] Test CSS loads correctly + +--- + +## Phase 3: SVG Icon System + +### 3.1 Extract Icons +- [ ] Identify all react-icons used: + - FaBars (hamburger menu) + - FaXmark (close X) + - FaGithub + - FaLinkedin + - FaEnvelope + - FaDatabase + - FaDocker + - FaReact + - SiCsharp + - SiMicrosoftazure + - SiBlazor +- [ ] Download SVG paths from icon sources (FontAwesome, Simple Icons) +- [ ] Create reusable Icon component: `Components/Icon.razor` + +### 3.2 Icon Component +- [ ] Implement `Icon.razor` with parameters: + - `Name` (string): icon identifier + - `Size` (int, default 24): icon size in pixels + - `CssClass` (string): additional CSS classes +- [ ] Store SVG paths in C# dictionary or switch statement +- [ ] Test all icons render correctly + +--- + +## Phase 4: Core Application Structure + +### 4.1 Routing Setup +- [ ] Configure routes in `App.razor`: + - `/` → Home page + - `/work` → Work page + - `/about` → About page + - `NotFound` → 404/Error page +- [ ] Test routing and navigation + +### 4.2 Layout Component +- [ ] Create `Shared/MainLayout.razor` +- [ ] Implement structure: + - Header with NavBar + - Main content area with `@Body` + - Footer +- [ ] Apply CSS classes (container, flex layout, min-height) +- [ ] Add fade-in animation class +- [ ] Test layout renders correctly + +### 4.3 Navigation Component +- [ ] Create `Shared/NavBar.razor` +- [ ] Implement desktop navigation: + - Logo image + - Navigation links (Home, Work, About) +- [ ] Implement mobile navigation: + - Hamburger button (toggle mobile menu) + - Mobile menu overlay with links + - Close button + - Social icons in mobile menu +- [ ] Use Blazor's built-in `NavLink` component with custom styling +- [ ] Implement mobile menu state with C# boolean property +- [ ] Style with pure CSS (no Headless UI) + +### 4.4 Footer Component +- [ ] Create `Shared/Footer.razor` +- [ ] Port footer content +- [ ] Apply styling + +--- + +## Phase 5: Page Components + +### 5.1 Home Page +- [ ] Create `Pages/Home.razor` with `@page "/"` +- [ ] Port content from `HomePage.tsx` +- [ ] Reference child components (Title, Text, TechIcons) +- [ ] Test rendering + +### 5.2 Work Page +- [ ] Create `Pages/Work.razor` with `@page "/work"` +- [ ] Port content from `WorkPage.tsx` +- [ ] Test rendering + +### 5.3 About Page +- [ ] Create `Pages/About.razor` with `@page "/about"` +- [ ] Port content from `AboutPage.tsx` +- [ ] Test rendering + +### 5.4 Error/404 Page +- [ ] Create `Pages/NotFound.razor` with `@page "/404"` +- [ ] Port content from `ErrorPage.tsx` +- [ ] Configure as NotFound in router +- [ ] Test 404 handling + +--- + +## Phase 6: Reusable UI Components + +### 6.1 Typography Components (7) +- [ ] `Components/Title.razor` - H1 heading +- [ ] `Components/Subtitle.razor` - H2 heading +- [ ] `Components/Text.razor` - Paragraph with margin +- [ ] `Components/Label.razor` - Form label +- [ ] `Components/List.razor` - UL wrapper +- [ ] `Components/ListItem.razor` - LI element +- [ ] `Components/AnchorLink.razor` - External link with styling + +### 6.2 Form Components (3) +- [ ] `Components/Button.razor` - Button with hover/focus states +- [ ] `Components/TextInput.razor` - Input field with label +- [ ] `Components/TextAreaInput.razor` - Textarea with label + +### 6.3 Display Components (5) +- [ ] `Components/TechIcons.razor` - Tech stack grid with icons +- [ ] `Components/SocialIcons.razor` - Social media links with icons +- [ ] `Components/WorkTimeline.razor` - Work experience timeline +- [ ] `Components/Loading.razor` - Loading state wrapper +- [ ] `Components/LoadingSpinner.razor` - Spinner animation + +### 6.4 Feature Components (2) +- [ ] `Components/ContactMe.razor` - Contact form +- [ ] `Components/AboutTabs.razor` - Tab interface (vanilla CSS/JS) + +--- + +## Phase 7: Interactive Components (Pure CSS - No JavaScript) + +### 7.1 Mobile Menu (CSS Checkbox Hack) +- [ ] Implement in `NavBar.razor`: + - Add hidden checkbox: `` + - Add label for hamburger: `` + - Add label for close button inside menu: `` + - Render menu panel as sibling to checkbox +- [ ] Style with CSS: + - Hide checkbox: `.menu-toggle { display: none; }` + - Show/hide menu based on checkbox state: `.menu-toggle:checked ~ .mobile-menu { ... }` + - Show/hide overlay: `.menu-toggle:checked ~ .overlay { ... }` + - Slide-in animation using `transform: translateX()` + - Transparent overlay with backdrop-filter blur + - Z-index layering for proper stacking +- [ ] Test keyboard navigation (checkbox is focusable) + +### 7.2 Tabs Component (CSS :target Pseudo-Class or Radio Buttons) +- [ ] **Option A - Radio Button Approach (Recommended):** + - Create `AboutTabs.razor`: + - Hidden radio inputs: `` + - Label buttons: `` + - Tab panels as siblings to inputs + - Style with CSS: + - Hide radio buttons: `input[type="radio"] { display: none; }` + - Active tab styling: `#tab1:checked ~ .tabs-labels label[for="tab1"] { ... }` + - Show panel: `#tab1:checked ~ .tab-panels .panel1 { display: block; }` + - Hide other panels by default +- [ ] **Option B - :target Pseudo-Class:** + - Use anchor links: `Tab 1` + - Panel IDs: `