Skip to content

Commit 286d097

Browse files
davidagustinclaude
andcommitted
feat: add Pickleball Research project and make githubUrl optional
- Make githubUrl optional in Project type (index.ts) - Conditionally render GitHub links in all 4 view locations (Projects.tsx) - Add project #28 Pickleball Research with empty githubUrl and live URL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7176937 commit 286d097

3 files changed

Lines changed: 82 additions & 40 deletions

File tree

src/components/Projects.tsx

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -246,16 +246,18 @@ const CarouselView: React.FC<{
246246
)}
247247
</div>
248248
<div className="flex items-center gap-3 pt-3 border-t border-surface-100 dark:border-surface-700">
249-
<a
250-
href={project.githubUrl}
251-
target="_blank"
252-
rel="noopener noreferrer"
253-
onClick={(e) => e.stopPropagation()}
254-
className="inline-flex items-center gap-1.5 text-xs font-medium text-surface-500 hover:text-surface-900 dark:hover:text-white transition-colors"
255-
>
256-
<FaGithub className="text-sm" />
257-
Code
258-
</a>
249+
{project.githubUrl && (
250+
<a
251+
href={project.githubUrl}
252+
target="_blank"
253+
rel="noopener noreferrer"
254+
onClick={(e) => e.stopPropagation()}
255+
className="inline-flex items-center gap-1.5 text-xs font-medium text-surface-500 hover:text-surface-900 dark:hover:text-white transition-colors"
256+
>
257+
<FaGithub className="text-sm" />
258+
Code
259+
</a>
260+
)}
259261
{project.liveUrl && (
260262
<a
261263
href={project.liveUrl}
@@ -388,16 +390,18 @@ const TableView: React.FC<{
388390
</td>
389391
<td className="px-5 py-6 text-right">
390392
<div className="flex items-center justify-end gap-3">
391-
<a
392-
href={project.githubUrl}
393-
target="_blank"
394-
rel="noopener noreferrer"
395-
onClick={(e) => e.stopPropagation()}
396-
className="p-2 rounded-lg text-surface-400 hover:text-surface-900 dark:hover:text-white hover:bg-surface-100 dark:hover:bg-surface-700 transition-colors"
397-
aria-label={`${project.title} source code`}
398-
>
399-
<FaGithub className="text-base" />
400-
</a>
393+
{project.githubUrl && (
394+
<a
395+
href={project.githubUrl}
396+
target="_blank"
397+
rel="noopener noreferrer"
398+
onClick={(e) => e.stopPropagation()}
399+
className="p-2 rounded-lg text-surface-400 hover:text-surface-900 dark:hover:text-white hover:bg-surface-100 dark:hover:bg-surface-700 transition-colors"
400+
aria-label={`${project.title} source code`}
401+
>
402+
<FaGithub className="text-base" />
403+
</a>
404+
)}
401405
{project.liveUrl && (
402406
<a
403407
href={project.liveUrl}
@@ -489,16 +493,18 @@ const GridView: React.FC<{
489493
</ul>
490494

491495
<div className="flex items-center gap-3 pt-4 border-t border-surface-100 dark:border-surface-700">
492-
<a
493-
href={project.githubUrl}
494-
target="_blank"
495-
rel="noopener noreferrer"
496-
onClick={(e) => e.stopPropagation()}
497-
className="inline-flex items-center gap-1.5 text-xs font-medium text-surface-500 hover:text-surface-900 dark:hover:text-white transition-colors"
498-
>
499-
<FaGithub className="text-sm" />
500-
Code
501-
</a>
496+
{project.githubUrl && (
497+
<a
498+
href={project.githubUrl}
499+
target="_blank"
500+
rel="noopener noreferrer"
501+
onClick={(e) => e.stopPropagation()}
502+
className="inline-flex items-center gap-1.5 text-xs font-medium text-surface-500 hover:text-surface-900 dark:hover:text-white transition-colors"
503+
>
504+
<FaGithub className="text-sm" />
505+
Code
506+
</a>
507+
)}
502508
{project.liveUrl && (
503509
<a
504510
href={project.liveUrl}
@@ -828,15 +834,17 @@ const Projects: React.FC = () => {
828834
</div>
829835

830836
<div className="flex flex-wrap items-center gap-3 pt-6 border-t border-surface-100 dark:border-surface-800">
831-
<a
832-
href={selectedProject.githubUrl}
833-
target="_blank"
834-
rel="noopener noreferrer"
835-
className="inline-flex items-center gap-2 px-5 py-2.5 bg-surface-900 dark:bg-white text-white dark:text-surface-900 rounded-lg text-sm font-medium hover:bg-surface-800 dark:hover:bg-surface-100 transition-colors"
836-
>
837-
<FaGithub />
838-
View Code
839-
</a>
837+
{selectedProject.githubUrl && (
838+
<a
839+
href={selectedProject.githubUrl}
840+
target="_blank"
841+
rel="noopener noreferrer"
842+
className="inline-flex items-center gap-2 px-5 py-2.5 bg-surface-900 dark:bg-white text-white dark:text-surface-900 rounded-lg text-sm font-medium hover:bg-surface-800 dark:hover:bg-surface-100 transition-colors"
843+
>
844+
<FaGithub />
845+
View Code
846+
</a>
847+
)}
840848
{selectedProject.liveUrl && (
841849
<a
842850
href={selectedProject.liveUrl}

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface Project {
1010
title: string;
1111
description: string;
1212
technologies: string[];
13-
githubUrl: string;
13+
githubUrl?: string;
1414
liveUrl?: string;
1515
category: string;
1616
features: string[];

src/utils/constants.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,4 +813,38 @@ export const PROJECTS: Project[] = [
813813
techDetails: 'Turborepo 2.0 monorepo with Expo 52 (React Native 0.76), Fastify 5, Socket.IO 4.8 + Redis adapter, Prisma 5.20 (PostgreSQL 16), Zustand 4.5, chess.js, NativeWind 4.1. Terraform for AWS, Nginx reverse proxy with SSL, and GitHub Actions CI/CD.',
814814
},
815815
},
816+
{
817+
id: 28,
818+
title: 'Pickleball Research',
819+
description:
820+
'The most comprehensive pickleball research platform on the web. 31 interactive pages covering 587 paddles, 160+ pro athletes, 130+ drills, 16 illustrated plays, live PPA tournament data, a tactical whiteboard, paddle physics simulator, paddle builder with 3D rendering, strategy decision trees, and a 46,000-line digital magazine. All data visualizations are hand-coded SVG with zero charting libraries.',
821+
technologies: ['Next.js 16', 'React 19', 'TypeScript 5', 'Tailwind CSS 4', 'Puppeteer', 'Cloudflare Workers'],
822+
githubUrl: '',
823+
liveUrl: 'https://pickleball-research.vercel.app',
824+
category: 'Research',
825+
features: [
826+
'587 Paddle Database',
827+
'160+ Pro Athletes',
828+
'130+ Drills Library',
829+
'Live Tournament Data',
830+
'Tactical Whiteboard',
831+
'Paddle Physics Lab',
832+
],
833+
readmeHighlights: {
834+
overview: 'The most comprehensive pickleball research platform — every shot, technique, pro player, paddle dimension, drill, and strategy in one place. 31 interactive pages with 100,000+ lines of code, custom SVG visualizations, and live PPA Tour data.',
835+
highlights: [
836+
'587 paddles from 36+ brands with card/table/radar views, multi-axis filters, and side-by-side comparison',
837+
'160+ PPA pro athlete profiles with DUPR, ELO, win rates, archetype classification, and gear data',
838+
'130+ drills across 11 categories with difficulty filters, impact ratings, video links, and save-to-collection',
839+
'Interactive paddle lab with clock-face weight simulator, real-time physics (swing wt, twist wt, balance), and 3D rotation',
840+
'Paddle builder: design from scratch with core/face/construction options, 6-axis performance scoring, and player fit analysis',
841+
'Tactical whiteboard with drag-and-drop players, 7 drawing tools, shot stamps, and undo/redo',
842+
'16 illustrated playbook plays with animated SVG court diagrams and movement paths',
843+
'Live PPA tournament data with match tickers, brackets, rankings across 6 categories, and event schedules',
844+
'46,000-line interactive digital magazine (Pickleball 101) with collapsible TOC and dual view modes',
845+
'Strategy decision tree engine with branching shot-selection and confidence percentages',
846+
],
847+
techDetails: 'Next.js 16 App Router with React 19, TypeScript 5, Tailwind CSS 4. Puppeteer data collection scripts, PPA Tour API proxy with in-memory caching, custom SVG visualizations (zero charting libraries), localStorage persistence with CSV import/export. Deployed on Cloudflare Workers via OpenNextJS adapter.',
848+
},
849+
},
816850
];

0 commit comments

Comments
 (0)