Skip to content

Commit

Permalink
Merge pull request #152 from jerboa88/150-create-resume-template
Browse files Browse the repository at this point in the history
150 create resume template
  • Loading branch information
jerboa88 authored Jun 30, 2024
2 parents 7912fb0 + b9eb437 commit 348fa8c
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 20 deletions.
3 changes: 2 additions & 1 deletion gatsby-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import {
getTheme,
} from './src/common/config-manager';
import { SOCIAL_IMAGES_DIR } from './src/common/constants';
import { ThemeType } from './src/common/types';
import { getAbsoluteUrl } from './src/common/utilities';
import tailwindConfig from './tailwind.config';

const SITE_METADATA = getSiteMetadata();
const DARK_THEME = getTheme('dark');
const DARK_THEME = getTheme(ThemeType.Dark);
const OG_IMAGE_GENERATION_CONFIG = getSocialImageGenerationConfigForType('og');

// Load environment variables from relevant .env file
Expand Down
14 changes: 10 additions & 4 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export type UrlString = `https://${string}`;
type DateString = `${20}${number}-${number}-${number}`;

// City and state string
type CityAndStateString = Capitalize<`${string}, ${string}`>;
export type CityAndStateString = Capitalize<`${string}, ${string}`>;

// Sentence string with proper capitalization and punctuation
type SentenceString = Capitalize<`${string}.` | `${string}!` | `${string}?`>;
export type SentenceString = Capitalize<`${string}${'.' | '!' | '?'}`>;

// Raw external services config
export interface ExternalServicesConfig {
Expand Down Expand Up @@ -126,6 +126,12 @@ export interface ImageMetadataProp {
imageMetadata: JobOptions;
}

// Theme names
export enum ThemeType {
Light = 'light',
Dark = 'dark',
}

// Theme object used to style the site
export type Theme = Partial<{
primary: string;
Expand All @@ -152,8 +158,8 @@ export type Theme = Partial<{

// Raw themes config used to generate theme objects
export interface ThemesConfig {
light: Theme;
dark: Theme;
[ThemeType.Light]: Theme;
[ThemeType.Dark]: Theme;
}

// Color mappings for project types
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/page-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Layout component that provides basic styles and metadata tags for the whole page
--------------------------------------------------------------------------------
Layout component that provides basic styles for the whole page
--------------------------------------------------------------
*/

import { MotionConfig } from 'framer-motion';
Expand Down
3 changes: 2 additions & 1 deletion src/components/layout/particles-background.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { loadSquareShape } from '@tsparticles/shape-square';
import { useReducedMotion } from 'framer-motion';
import { memo, useEffect, useState } from 'react';
import { getTheme } from '../../common/config-manager';
import { ThemeType } from '../../common/types';
import { getClassNameProps } from '../../common/utilities';

// Constants

// TODO: Replace hardcoded value here
const THEME = getTheme('dark');
const THEME = getTheme(ThemeType.Dark);

function UnmemoizedParticlesBackground() {
const shouldReduceMotion = useReducedMotion();
Expand Down
34 changes: 34 additions & 0 deletions src/components/layout/resume-page-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Layout component that provides basic styles for the resume page
---------------------------------------------------------------
*/

import { MotionConfig } from 'framer-motion';
import { type PropsWithChildren, StrictMode } from 'react';
import { SPRING_TRANSITION_PROPS } from '../../common/constants';
import { type PropsWithClassName, ThemeType } from '../../common/types';
import { getClassNameProps } from '../../common/utilities';
import { ResumeHeader } from './resume-header';

// Types

interface Props extends PropsWithClassName, PropsWithChildren {}

export function ResumePageLayout({ className, children }: Props) {
const classNameProps = getClassNameProps(
'flex-col gap-32 p-[1cm] justify-between items-center mx-auto text-base min-h-svh scroll-smooth selection:bg-primary selection:text-primary-content',
className,
);

return (
<StrictMode>
<MotionConfig {...SPRING_TRANSITION_PROPS} reducedMotion="user">
{/* Page body */}
<div data-theme={ThemeType.Light} {...classNameProps}>
<ResumeHeader />
{children}
</div>
</MotionConfig>
</StrictMode>
);
}
2 changes: 1 addition & 1 deletion src/components/layout/section-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { SectionHeading } from '../text/section-heading';

interface Props extends PropsWithClassName, PropsWithChildren {
title: string;
renderButton?: ButtonElementRenderFunction;
renderButton?: ButtonElementRenderFunction | undefined;
}

export function SectionHeader({ className, title, renderButton }: Props) {
Expand Down
11 changes: 10 additions & 1 deletion src/components/layout/section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,22 @@ import { getClassNameProps, toKebabCase } from '../../common/utilities';
import { SectionHeader } from './section-header';

interface Props extends PropsWithClassName, PropsWithChildren {
sectionHeaderClassName?: string;
title?: string;
renderButton?: ButtonElementRenderFunction;
responsive?: boolean;
}

export const Section = forwardRef(
(
{ className, title, renderButton, responsive = true, children }: Props,
{
className,
sectionHeaderClassName,
title,
renderButton,
responsive = true,
children,
}: Props,
ref: ForwardedRef<HTMLElement>,
) => {
const classNameProps = getClassNameProps(
Expand All @@ -29,6 +37,7 @@ export const Section = forwardRef(
);
const sectionHeaderClassNameProps = getClassNameProps(
responsive && 'pt-10', // Add padding to account for floating page header
sectionHeaderClassName,
);

const sectionId = title ? toKebabCase(title) : 'top';
Expand Down
64 changes: 64 additions & 0 deletions src/components/resume-entry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
A single resume entry for a role, project, etc.
-----------------------------------------------
*/

import type {
CityAndStateString,
SentenceString,
UrlString,
} from '../common/types';
import { LinkWrapper } from './links/link-wrapper';
import { Article } from './text/article';
import { DateRange } from './text/date-range';
import { SubsectionHeading } from './text/subsection-heading';

interface Props {
title: Capitalize<string>;
tagline: Capitalize<string>;
bullets: SentenceString[];
url?: UrlString;
startDate?: Date;
endDate?: Date;
location?: CityAndStateString;
}

export function ResumeEntry({
title,
tagline,
bullets,
url,
startDate,
endDate,
location,
}: Props) {
return (
<div className="flex flex-row justify-between items-start gap-4">
<div className="flex flex-col">
<div className="flex flex-row items-center gap-4">
<LinkWrapper to={url}>
<SubsectionHeading>{title}</SubsectionHeading>
</LinkWrapper>
<span className="italic">{tagline}</span>
</div>
<Article>
<ul>
{bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</Article>
</div>
<div>
<div className="max-lg:pl-1 flex flex-col items-end">
<DateRange
startDate={startDate}
endDate={endDate}
className="text-nowrap"
/>
{location && <span>{location}</span>}
</div>
</div>
</div>
);
}
9 changes: 5 additions & 4 deletions src/components/seo/page-head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/

import { getSiteMetadata, getTheme } from '../../common/config-manager';
import type {
PageMetadata,
SocialImagesMetadataProp,
import {
type PageMetadata,
type SocialImagesMetadataProp,
ThemeType,
} from '../../common/types';
import { getAbsoluteUrl, getMimeType } from '../../common/utilities';

Expand All @@ -22,7 +23,7 @@ interface Props extends SocialImagesMetadataProp {

const SITE_METADATA = getSiteMetadata();
// TODO: Replace hardcoded value
const THEME = getTheme('dark');
const THEME = getTheme(ThemeType.Dark);

export function PageHead({
path,
Expand Down
6 changes: 3 additions & 3 deletions src/config/themes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
---------------------------
*/

import type { ThemesConfig } from '../common/types';
import { ThemeType, type ThemesConfig } from '../common/types';

export const themesConfig: ThemesConfig = {
light: {
[ThemeType.Light]: {
primary: '#0F766E', // TW Teal 700
secondary: '#E11D48', // TW Rose 600
accent: '#E11D48', // TW Rose 600
Expand All @@ -21,7 +21,7 @@ export const themesConfig: ThemesConfig = {
'base-content': '#000', // Pure black
'neutral-content': '#000',
},
dark: {
[ThemeType.Dark]: {
primary: '#2DD4BF', // TW Teal 400
secondary: '#FB7185', // TW Rose 400
accent: '#E11D48', // TW Rose 600
Expand Down
10 changes: 7 additions & 3 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import type { Config } from 'tailwindcss';
import plugin from 'tailwindcss/plugin';
import { getTheme } from './src/common/config-manager';
import { ThemeType } from './src/common/types';

export default {
content: ['src/**/*.{js,jsx,ts,tsx}'],
darkMode: ['class', '[data-theme="dark"]'],
darkMode: ['class', `[data-theme="${ThemeType.Dark}"]`],
theme: {
fontFamily: {
sans: [
Expand Down Expand Up @@ -69,7 +70,10 @@ export default {
}),
],
daisyui: {
themes: [{ dark: getTheme('dark') }, { light: getTheme('light') }],
darkTheme: 'dark',
themes: [
{ [ThemeType.Dark]: getTheme(ThemeType.Dark) },
{ [ThemeType.Light]: getTheme(ThemeType.Light) },
],
darkTheme: ThemeType.Dark,
},
} satisfies Config;

0 comments on commit 348fa8c

Please sign in to comment.