diff --git a/src/app/page.tsx b/src/app/page.tsx index fc0ca36..b9f01ab 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,26 +1,154 @@ -import React from 'react' +'use client' + +import React, { useState } from 'react' import { Project } from '@/typings/project' import { ProjectCard } from '@/components/ProjectCard' -export default function Page() { +const Page = () => { const projects: Project[] = [ { - name: 'test', - description: 'test', - category: 'Misc', - imageUrl: 'https://avatars.githubusercontent.com/u/48355802?v=4', - socials: {}, - languages: ['Rust'], + 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 [currentPage, setCurrentPage] = useState(1) + const [itemsPerPage] = 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) + setCurrentPage(1) // Reset to the first page when filter changes + } + + const handleSortChange = (event: React.ChangeEvent) => { + setSortOrder(event.target.value as 'asc' | 'desc') + setCurrentPage(1) // Reset to the first page when sort order changes + } + + const filteredProjects = filterTag + ? projects.filter(project => project.tags.includes(filterTag)) + : projects + + const sortedProjects = [...filteredProjects].sort((a, b) => { + if (sortOrder === 'asc') { + return a.name.localeCompare(b.name) + } else { + return b.name.localeCompare(a.name) + } + }) + + const indexOfLastItem = currentPage * itemsPerPage + const indexOfFirstItem = indexOfLastItem - itemsPerPage + const currentProjects = sortedProjects.slice( + indexOfFirstItem, + indexOfLastItem + ) + + const totalPages = Math.ceil(sortedProjects.length / itemsPerPage) + return (
-
Matz Hilven
- {projects.map((project: Project, index: number) => { - return - })} +
Matz Hilven
+
+ + +
+
+ {currentProjects.map((project: Project, index: number) => ( + + ))} +
+
+ + +
) } + +export default Page diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx index c669243..af25866 100644 --- a/src/components/ProjectCard.tsx +++ b/src/components/ProjectCard.tsx @@ -1,15 +1,86 @@ -import { Project } from '@/typings/project' +import { Project, Tag, Language, Social } from '@/typings/project' +import { + IconBrandGithub, + IconBrandYoutube, + IconCoffee, + IconBrandRust, + IconBrandGolang, + IconBrandTypescript, +} from '@tabler/icons-react' type Props = { project: Project } +const socialIcons: Record = { + Github: , + YouTube: , +} + +const languageIcons: Record = { + Java: , + Rust: , + Go: , + TypeScript: , +} + +const tagStyles: Record = { + '1.8': 'text-orange-500 border-orange-500', + '1.17': 'text-orange-500 border-orange-500', + Paper: 'text-blue-500 border-blue-500', + Bungee: 'text-blue-500 border-blue-500', + Frontend: 'text-cyan-500 border-cyan-500', + Backend: 'text-cyan-500 border-cyan-500', + Fullstack: 'text-cyan-500 border-cyan-500', + Archived: 'text-gray-600 border-gray-600', +} + export const ProjectCard = ({ project }: Props) => { return ( -
-
{project.name}
-
{project.description}
- +
+ {project.name} +
+
+
{project.name}
+
+ {project.tags.map(tag => ( + + {tag} + + ))} +
+
{project.description}
+
+
+
+ {Object.entries(project.socials).map(([social, url]) => ( + + {socialIcons[social as Social]} + + ))} +
+
+ {project.languages.map(language => ( + + {languageIcons[language]} + + ))} +
+
+
) } diff --git a/src/typings/project.ts b/src/typings/project.ts index 67f7ded..e768f64 100644 --- a/src/typings/project.ts +++ b/src/typings/project.ts @@ -1,11 +1,11 @@ -type Social = 'Github' | 'YouTube' -type Language = 'Java' | 'Rust' | 'Go' | 'TypeScript' +export type Social = 'Github' | 'YouTube' +export type Language = 'Java' | 'Rust' | 'Go' | 'TypeScript' type MinecraftTags = '1.8' | '1.17' | 'Paper' | 'Bungee' type WebTags = 'Frontend' | 'Backend' | 'Fullstack' -type Tag = MinecraftTags | WebTags | 'Archived' +export type Tag = MinecraftTags | WebTags | 'Archived' -type Category = 'Minecraft' | 'Web' | 'Discord' | 'Misc' | 'Unity' +export type Category = 'Minecraft' | 'Web' | 'Discord' | 'Misc' | 'Unity' export type Project = { name: string