Skip to content

Commit

Permalink
feat: Add tech stack tags to ProjectCard component (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
lemonteaau authored Jul 10, 2024
1 parent a9b001f commit 0dbed4c
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/app/open-source/FutureProjectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import FancyRectangle from '@/components/FancyRectangle';
import Tag from '@/components/Tag';
import { TECH_COLORS } from '@/constants/colours';
import type { FutureProject } from '@/data/future-projects';

export default function ProjectCard({ project }: { project: FutureProject }) {
return (
<FancyRectangle colour="white" offset="8" rounded fullWidth>
<div className="w-full gap-6 rounded-xl bg-white p-4 text-black">
<div className="space-y-2 md:space-y-4">
<div className="gap-6">
<div className="space-y-2">
<h4 className="text-2xl font-bold md:pb-1 md:text-3xl">
{project.title}
</h4>
<p>{project.description}</p>
</div>
</div>
{project.techStacks.length !== 0 && (
<div className="flex flex-wrap gap-3">
{project.techStacks.map((tech, i) => (
<Tag key={i} name={tech} backgroundColor={TECH_COLORS[tech]} />
))}
</div>
)}
</div>
</div>
</FancyRectangle>
);
}
7 changes: 7 additions & 0 deletions src/app/open-source/ProjectCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Button from '@/components/Button';
import FancyRectangle from '@/components/FancyRectangle';
import Tag from '@/components/Tag';
import { TECH_COLORS } from '@/constants/colours';
import type { Project } from '@/data/projects';
import Image from 'next/image';
import { FaGithub } from 'react-icons/fa';
Expand All @@ -24,6 +26,11 @@ export default function ProjectCard({ project }: { project: Project }) {
<p>{project.description}</p>
</div>
</div>
<div className="flex flex-wrap gap-3">
{project.techStacks.map((tech, i) => (
<Tag key={i} name={tech} backgroundColor={TECH_COLORS[tech]} />
))}
</div>
<Button
colour="orange"
href={project.githubLink}
Expand Down
10 changes: 10 additions & 0 deletions src/app/open-source/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Title from '@/components/Title';
import { FUTURE_PROJECTS } from '@/data/future-projects';
import { PROJECTS } from '@/data/projects';
import type { Metadata } from 'next';
import FutureProjectCard from './FutureProjectCard';
import ProjectCard from './ProjectCard';

export const metadata: Metadata = {
Expand Down Expand Up @@ -32,6 +34,14 @@ export default function OpenSourcePage() {
))}
</div>
</section>
<section className="mb-8">
<h2 className="mb-4 text-2xl font-bold">Future Projects</h2>
<div className="grid gap-8 sm:grid-cols-1 md:grid-cols-2">
{FUTURE_PROJECTS.map((project, i) => (
<FutureProjectCard key={i} project={project} />
))}
</div>
</section>
<section className="mb-8">
<h2 className="mb-4 text-2xl font-bold">How to join?</h2>
<p className="text-lg md:text-xl">
Expand Down
19 changes: 19 additions & 0 deletions src/components/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getContrastColor } from '@/constants/colours';

interface TagProps {
name: string;
backgroundColor: string;
}

export default function Tag({ name, backgroundColor }: TagProps) {
const textColor: string = getContrastColor(backgroundColor);

return (
<div
className="h-fit w-fit rounded-xl border-2 border-black px-3 py-1.5"
style={{ backgroundColor, color: textColor }}
>
<span>{name}</span>
</div>
);
}
30 changes: 30 additions & 0 deletions src/constants/colours.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { TechStack } from '@/constants/tech-stack';

export type Colour = 'black' | 'grey' | 'lightGrey' | 'white' | 'yellow' | 'orange' | 'purple';

export const BG_COLOURS = {
Expand All @@ -19,3 +21,31 @@ export const BORDER_COLOURS = {
orange: 'border-orange border-2',
purple: 'border-purple border-2',
} as const satisfies Record<Colour, string>;

export const TECH_COLORS = {
'Discord.py': '#7387CE',
FastAPI: '#F6BF00',
'Next.js': '#B17CA6',
Python: '#64B550',
React: '#ED8C9B',
Supabase: '#5DBBB5',
'Tailwind CSS': '#907FC3',
TypeScript: '#ACCB00',
} as const satisfies Record<TechStack, string>;

/**
* Based on code from matfin. Source: https://stackoverflow.com/a/44615197/24033621, licensed under
* CC BY-SA 3.0.
*
* @param {string} backgroundColor - The hex color string to calculate contrast for.
* @returns {string} - The contrast color, either '#000000' (black) or '#FFFFFF' (white).
*/
export const getContrastColor = (backgroundColor: string): string => {
const hex = backgroundColor.replace(/^#/, '');
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
const textColor = luminance > 0.5 ? '#000000' : '#FFFFFF';
return textColor;
};
11 changes: 11 additions & 0 deletions src/constants/tech-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const TECH_STACK = [
'Python',
'FastAPI',
'TypeScript',
'React',
'Next.js',
'Tailwind CSS',
'Supabase',
'Discord.py',
] as const;
export type TechStack = (typeof TECH_STACK)[number];
33 changes: 33 additions & 0 deletions src/data/future-projects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { TechStack } from '@/constants/tech-stack';

export interface FutureProject {
title: string;
description: string;
techStacks: TechStack[];
}

export const FUTURE_PROJECTS: FutureProject[] = [
{
title: 'Courses API',
description:
'Scrapes course info from the UofA website and provides course data for other projects through an API endpoint.',
techStacks: ['Python', 'FastAPI'],
},
{
title: 'MyTimetable',
description:
'An interactive drag-and-drop timetable scheduler to help UofA students optimise their weekly timetable.',
techStacks: ['TypeScript', 'React', 'Next.js', 'Tailwind CSS'],
},
{
title: 'MyStudyPlan',
description:
'A UofA degree planner that allows you to explore and validate your degree structure.',
techStacks: ['TypeScript', 'React', 'Next.js', 'Tailwind CSS'],
},
{
title: 'MyCourseReviews',
description: 'Allows students to share reviews and rate UofA courses.',
techStacks: ['TypeScript', 'React', 'Next.js', 'Tailwind CSS', 'Supabase'],
},
];
5 changes: 5 additions & 0 deletions src/data/projects.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { TechStack } from '@/constants/tech-stack';

export interface Project {
title: string;
description: string;
image: string;
githubLink: string;
techStacks: TechStack[];
}

export const PROJECTS: Project[] = [
Expand All @@ -11,11 +14,13 @@ export const PROJECTS: Project[] = [
description: "The Computer Science Club's website.",
image: 'website.png',
githubLink: 'https://github.com/compsci-adl/website',
techStacks: ['Next.js', 'React', 'TypeScript', 'Tailwind CSS'],
},
{
title: 'DuckBot',
description: "A Discord bot for the CS Club's Discord Server.",
image: 'duckbot.png',
githubLink: 'https://github.com/compsci-adl/duckbot',
techStacks: ['Python', 'Discord.py'],
},
];

0 comments on commit 0dbed4c

Please sign in to comment.