From 38a7e09b689566f3c789504f0a3dcec778b3bf8f Mon Sep 17 00:00:00 2001 From: Matz Hilven Date: Thu, 30 May 2024 08:51:53 +0200 Subject: [PATCH] feat: better --- package.json | 3 +- pnpm-lock.yaml | 7 + public/projects.json | 1141 ++++++++++++++++++++++++++++++++ src/app/page.tsx | 103 +-- src/components/ProjectCard.tsx | 2 +- src/typings/project.ts | 58 +- 6 files changed, 1225 insertions(+), 89 deletions(-) create mode 100644 public/projects.json diff --git a/package.json b/package.json index 9f22cd3..04b3ef5 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "react-dom": "^18.3.1", "sharp": "^0.33.4", "tailwind-merge": "^2.3.0", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20.12.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21968fb..d05e24a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ dependencies: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.3) + zod: + specifier: ^3.23.8 + version: 3.23.8 devDependencies: '@types/node': @@ -3639,3 +3642,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false diff --git a/public/projects.json b/public/projects.json new file mode 100644 index 0000000..ca7dc80 --- /dev/null +++ b/public/projects.json @@ -0,0 +1,1141 @@ +[ + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + + { + "name": "Project Alpha", + "description": "Description for Project Alpha", + "category": "Web", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Java", "TypeScript"], + "tags": ["Frontend", "Backend"] + }, + { + "name": "Project Beta", + "description": "Description for Project Beta", + "category": "Minecraft", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "Github": "https://github.com" }, + "languages": ["Rust", "Go"], + "tags": ["1.8", "Fullstack"] + }, + { + "name": "Project Gamma", + "description": "Description for Project Gamma", + "category": "Discord", + "imageUrl": "https://via.placeholder.com/150", + "socials": { "YouTube": "https://youtube.com" }, + "languages": ["TypeScript"], + "tags": ["Backend", "Archived"] + }, + { + "name": "Project Delta", + "description": "Description for Project Delta", + "category": "Unity", + "imageUrl": "https://via.placeholder.com/150", + "socials": {}, + "languages": ["Java"], + "tags": ["1.17", "Frontend"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + }, + { + "name": "Project Epsilon", + "description": "Description for Project Epsilon", + "category": "Misc", + "imageUrl": "https://via.placeholder.com/150", + "socials": { + "Github": "https://github.com", + "YouTube": "https://youtube.com" + }, + "languages": ["Go", "Rust"], + "tags": ["Fullstack", "Paper"] + } +] diff --git a/src/app/page.tsx b/src/app/page.tsx index b9f01ab..824df0a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,85 +1,29 @@ 'use client' -import React, { useState } from 'react' -import { Project } from '@/typings/project' +import React, { useState, useEffect } from 'react' +import { Project, Tag, projectsSchema } from '@/typings/project' import { ProjectCard } from '@/components/ProjectCard' +import projectsData from '../../public/projects.json' const Page = () => { - const projects: Project[] = [ - { - name: 'Project Alpha', - description: 'Description for Project Alpha', - category: 'Web', - imageUrl: 'https://via.placeholder.com/150', - socials: { Github: 'https://github.com', YouTube: 'https://youtube.com' }, - languages: ['Java', 'TypeScript'], - tags: ['Frontend', 'Backend'], - }, - { - name: 'Project Beta', - description: 'Description for Project Beta', - category: 'Minecraft', - imageUrl: 'https://via.placeholder.com/150', - socials: { Github: 'https://github.com' }, - languages: ['Rust', 'Go'], - tags: ['1.8', 'Fullstack'], - }, - { - name: 'Project Gamma', - description: 'Description for Project Gamma', - category: 'Discord', - imageUrl: 'https://via.placeholder.com/150', - socials: { YouTube: 'https://youtube.com' }, - languages: ['TypeScript'], - tags: ['Backend', 'Archived'], - }, - { - name: 'Project Delta', - description: 'Description for Project Delta', - category: 'Unity', - imageUrl: 'https://via.placeholder.com/150', - socials: {}, - languages: ['Java'], - tags: ['1.17', 'Frontend'], - }, - { - name: 'Project Epsilon', - description: 'Description for Project Epsilon', - category: 'Misc', - imageUrl: 'https://via.placeholder.com/150', - socials: { Github: 'https://github.com', YouTube: 'https://youtube.com' }, - languages: ['Go', 'Rust'], - tags: ['Fullstack', 'Paper'], - }, - // Add more projects to test pagination - { - name: 'Project Zeta', - description: 'Description for Project Zeta', - category: 'Misc', - imageUrl: 'https://via.placeholder.com/150', - socials: { Github: 'https://github.com', YouTube: 'https://youtube.com' }, - languages: ['Go', 'Rust'], - tags: ['Fullstack', 'Paper'], - }, - { - name: 'Project Eta', - description: 'Description for Project Eta', - category: 'Misc', - imageUrl: 'https://via.placeholder.com/150', - socials: { Github: 'https://github.com', YouTube: 'https://youtube.com' }, - languages: ['Go', 'Rust'], - tags: ['Fullstack', 'Paper'], - }, - // Add as many projects as needed to test - ] + const parsedProjects = projectsSchema.safeParse(projectsData) + + if (!parsedProjects.success) { + console.error('Invalid project data', parsedProjects.error) + return
Error loading projects
+ } + + const projects: Project[] = parsedProjects.data const [currentPage, setCurrentPage] = useState(1) - const [itemsPerPage] = useState(4) - const [filterTag, setFilterTag] = useState(null) + const [itemsPerPage, setItemsPerPage] = useState(4) + const [filterTag, setFilterTag] = useState(null) const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc') const handleFilterChange = (event: React.ChangeEvent) => { - setFilterTag(event.target.value === 'All' ? null : event.target.value) + setFilterTag( + event.target.value === 'All' ? null : (event.target.value as Tag) + ) setCurrentPage(1) // Reset to the first page when filter changes } @@ -88,6 +32,21 @@ const Page = () => { setCurrentPage(1) // Reset to the first page when sort order changes } + useEffect(() => { + const handleResize = () => { + const cardWidth = 240 // Width of a single card (adjust as needed) + const windowWidth = window.innerWidth + const newItemsPerPage = Math.floor(windowWidth / cardWidth) + setItemsPerPage(newItemsPerPage > 0 ? newItemsPerPage : 1) + } + + handleResize() + + window.addEventListener('resize', handleResize) + + return () => window.removeEventListener('resize', handleResize) + }, []) + const filteredProjects = filterTag ? projects.filter(project => project.tags.includes(filterTag)) : projects diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx index af25866..cfde2e0 100644 --- a/src/components/ProjectCard.tsx +++ b/src/components/ProjectCard.tsx @@ -37,7 +37,7 @@ const tagStyles: Record = { export const ProjectCard = ({ project }: Props) => { return ( -
+
{project.name} -export type Category = 'Minecraft' | 'Web' | 'Discord' | 'Misc' | 'Unity' +export const LanguageSchema = z.union([ + z.literal('Java'), + z.literal('Rust'), + z.literal('Go'), + z.literal('TypeScript'), +]) +export type Language = z.infer -export type Project = { - name: string - description: string - category: Category - imageUrl: string - socials: Partial> - languages: Language[] - tags: Tag[] -} +export const TagSchema = z.union([ + z.literal('1.8'), + z.literal('1.17'), + z.literal('Paper'), + z.literal('Bungee'), + z.literal('Frontend'), + z.literal('Backend'), + z.literal('Fullstack'), + z.literal('Archived'), +]) +export type Tag = z.infer + +export const CategorySchema = z.union([ + z.literal('Minecraft'), + z.literal('Web'), + z.literal('Discord'), + z.literal('Misc'), + z.literal('Unity'), +]) +export type Category = z.infer + +export const ProjectSchema = z.object({ + name: z.string(), + description: z.string(), + category: CategorySchema, + imageUrl: z.string().url(), + socials: z.record(SocialSchema, z.string().url()).optional(), + languages: z.array(LanguageSchema), + tags: z.array(TagSchema), +}) +export type Project = z.infer + +export const projectsSchema = z.array(ProjectSchema)