diff --git a/app/page.tsx b/app/page.tsx index ad5784c..5458528 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,5 @@ import AboutSummary from "@/components/about-summary"; +import CommercialProjects from "@/components/commercial-projects"; import Experience from "@/components/experience"; import Hero from "@/components/hero"; import Skills from "@/components/skills"; @@ -11,6 +12,7 @@ export default function Home() {
+
diff --git a/components/commercial-project-card.tsx b/components/commercial-project-card.tsx new file mode 100644 index 0000000..80b4de2 --- /dev/null +++ b/components/commercial-project-card.tsx @@ -0,0 +1,59 @@ +import Link from "next/link"; +import { Project } from "@/lib/types"; +import Chip from "@/components/chip"; +import { Eye } from "lucide-react"; + +const CommercialProjectCard = ({ project }: { project: Project }) => { + return ( + // Removed h-full to allow flexbox stretch to control height +
+
+
+

+ {project.name} +

+ {project.commercial && ( + + COMMERCIAL + + )} +
+

+ {project.short_description} +

+
+ {project.technologies.slice(0, 4).map((tech) => ( + + ))} + {project.technologies.length > 4 && ( + + +{project.technologies.length - 4} more + + )} +
+
+ +
+ + Read more + + {project.visit_url && ( + + + + )} +
+
+ ); +}; + +export default CommercialProjectCard; diff --git a/components/commercial-projects.tsx b/components/commercial-projects.tsx new file mode 100644 index 0000000..050d3e9 --- /dev/null +++ b/components/commercial-projects.tsx @@ -0,0 +1,32 @@ +import { projects } from "@/lib/data"; +import CommercialProjectCard from "@/components/commercial-project-card"; + +const CommercialProjects = () => { + const commercialProjects = projects.filter((p) => p.commercial); + + return ( +
+
+

+ Commissioned Work 💼 +

+

+ Selected commercial projects and freelance commissions. +

+
+ +
+
+ {commercialProjects.map((project) => ( + + ))} +
+
+
+ ); +}; + +export default CommercialProjects; diff --git a/lib/data.ts b/lib/data.ts index 3f266a7..37bfe73 100644 --- a/lib/data.ts +++ b/lib/data.ts @@ -226,5 +226,160 @@ export const projects: Project[] = [ "TailwindCSS" ], "thumbnails": [] + }, + { + "id": 6, + "name": "Thoughts", + "short_description": "A nostalgic social platform prioritizing chronological feeds and user customization.", + "description": "Thoughts is a deliberate step away from algorithm-driven feeds. The vision is to create a digital \"third place\" that prioritizes genuine connection and user control, all wrapped in a nostalgic Frutiger Aero aesthetic.\n\nHere are the core principles I built this on:\n- **Chronological Above All:** Your feed is your feed, sorted by time. No algorithms, no \"you might also like.\"\n- **Radical Self-Expression:** Profiles are a canvas. I've brought back the ability for users to customize their pages with their own CSS, just like the good old days.\n- **Built for the Fediverse:** ActivityPub integration isn't in this MVP, but it's a top priority for the future to connect Thoughts with the wider decentralized web.\n\n**Technical details:**\n- **Backend:** Rust (Axum)\n- **Frontend:** Next.js\n- **Infrastructure:** Dockerized", + "category": "Web", + "github_url": "https://git.gabrielkaszewski.dev/GKaszewski/thoughts", + "visit_url": "https://thoughts.gabrielkaszewski.dev/", + "download_url": null, + "technologies": [ + "Rust", + "Axum", + "Next.js", + "Docker", + "TailwindCSS" + ], + "thumbnails": [] + }, + { + "id": 7, + "name": "Fleet Compass", + "short_description": "SaaS solution for modern fleet management.", + "description": "Fleet Compass is a comprehensive SaaS platform designed to streamline fleet management operations. It provides real-time tracking, analytics, and management tools to help businesses optimize their logistics.", + "category": "Web", + "github_url": null, + "visit_url": "https://fleetcompass.pl/", + "download_url": null, + "technologies": [ + "React", + "Python", + "Django", + "PostgreSQL", + "PostGIS", + "TailwindCSS" + ], + "thumbnails": [], + "commercial": true, + }, + { + "id": 8, + "name": "Poczuj - Szkoła z Lasu", + "short_description": "Interactive music composition app for children.", + "description": "A commissioned project for \"Szkoła z Lasu\". This application is an interactive tool designed for children, allowing them to compose music that reflects their current emotions. It combines educational values with creative expression, helping young users understand and express their feelings through sound.", + "category": "Web", + "github_url": null, + "visit_url": "https://poczuj.szkolazlasu.pl/", + "download_url": null, + "technologies": [ + "React", + ], + "thumbnails": [], + "commercial": true, + }, + { + "id": 9, + "name": "Codebase to Prompt", + "short_description": "CLI tool to convert codebase context into LLM prompts.", + "description": "A Rust-based Command Line Interface (CLI) tool designed to aggregate and format a codebase into a single prompt suitable for Large Language Models (LLMs). This tool streamlines the process of sharing code context with AI assistants.", + "category": "Desktop", + "github_url": "https://github.com/GKaszewski/codebase-to-prompt", + "visit_url": "https://crates.io/crates/codebase-to-prompt", + "download_url": null, + "technologies": [ + "Rust", + ], + "thumbnails": [] + }, + { + "id": 10, + "name": "Parasitic God", + "short_description": "Game Jam entry created in Godot.", + "description": "A game created during a Game Jam. It explores themes of cosmic horror and parasitic control. Developed using the Godot Engine.", + "category": "Game", + "github_url": null, + "visit_url": "https://gabrielkaszewski.itch.io/parasitic-god", + "download_url": null, + "technologies": [ + "Godot", + "C#" + ], + "thumbnails": [] + }, + { + "id": 11, + "name": "Broberry", + "short_description": "Action-packed Game Jam entry.", + "description": "A fun and fast-paced game developed for a Game Jam. Check it out on Itch.io!", + "category": "Game", + "github_url": null, + "visit_url": "https://gabrielkaszewski.itch.io/broberry", + "download_url": null, + "technologies": [ + "Unity", + "C#" + ], + "thumbnails": [] + }, + { + "id": 12, + "name": "Chip8 Emulator", + "short_description": "CHIP-8 interpreter written in Rust.", + "description": "A fully functional emulator for the CHIP-8 programming language, written in Rust. It demonstrates low-level programming concepts and system emulation.", + "category": "Desktop", + "github_url": "https://github.com/GKaszewski/chip8", + "visit_url": null, + "download_url": null, + "technologies": [ + "Rust", + "Raylib" + ], + "thumbnails": [] + }, + { + "id": 13, + "name": "Godot LDtk Importer", + "short_description": "Plugin to import LDtk maps into Godot.", + "description": "A tool designed to bridge the gap between the LDtk level editor and the Godot Game Engine. It streamlines the workflow for developers using LDtk for level design.", + "category": "Desktop", + "github_url": "https://github.com/GKaszewski/godot-ldtk-importer", + "visit_url": null, + "download_url": null, + "technologies": [ + "Godot", + "C#" + ], + "thumbnails": [] + }, + { + "id": 14, + "name": "Simple Cloudflare DDNS", + "short_description": "Dynamic DNS updater for Cloudflare.", + "description": "A lightweight utility to automatically update Cloudflare DNS records with your dynamic IP address. Useful for home labs and self-hosting setups.", + "category": "Api", + "github_url": "https://github.com/GKaszewski/simple_cloudflare_ddns", + "visit_url": null, + "download_url": null, + "technologies": [ + "Rust" + ], + "thumbnails": [] + }, + { + "id": 15, + "name": "QR Generator", + "short_description": "Fast and simple QR code generator.", + "description": "A utility tool for generating QR codes instantly.", + "category": "Api", + "github_url": "https://github.com/GKaszewski/qr-generator", + "visit_url": null, + "download_url": null, + "technologies": [ + "Rust", + ], + "thumbnails": [] } ]; diff --git a/lib/types.ts b/lib/types.ts index a173655..2a496aa 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -23,4 +23,5 @@ export interface Project { github_url?: string | null; visit_url?: string | null; download_url?: string | null; + commercial?: boolean; } \ No newline at end of file