-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c6b6eb0
commit 5c971da
Showing
86 changed files
with
3,642 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: CI | ||
on: push | ||
|
||
jobs: | ||
ci: | ||
name: CI | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: pnpm/action-setup@v4 | ||
- name: Use Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 'lts/*' | ||
cache: 'pnpm' | ||
- run: pnpm install | ||
- run: pnpm eslint . --max-warnings 0 | ||
- run: pnpm tsc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,91 @@ | ||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). | ||
# Business Portfolio Website | ||
|
||
## Getting Started | ||
This repository contains the code for the business portfolio website [jonaschlegel.com](https://jonaschlegel.com), showcasing Jona Schlegel’s projects in archaeological science communication, illustration, and web development. | ||
|
||
First, run the development server: | ||
## Technologies Used | ||
|
||
- **Framework**: [Next.js 13+](https://nextjs.org/) | ||
- **Package Manager**: [pnpm](https://pnpm.io/) | ||
- **Styling**: [Tailwind CSS](https://tailwindcss.com/) | ||
- **TypeScript**: For type safety and improved developer experience. | ||
- **ESLint**: [UpLeveled ESLint Config](https://github.com/upleveled/eslint-config-upleveled) for linting and code quality. | ||
|
||
## Setup and Installation | ||
|
||
To set up the project locally, follow these steps: | ||
|
||
1. **Clone the repository**: | ||
|
||
```bash | ||
git clone https://github.com/<your-username>/business-portfolio.git | ||
cd business-portfolio | ||
``` | ||
|
||
2. **Install dependencies using pnpm**: | ||
|
||
```bash | ||
pnpm install | ||
``` | ||
|
||
3. **Start the development server**: | ||
|
||
```bash | ||
pnpm dev | ||
``` | ||
|
||
The site will be running locally at `http://localhost:3000`. | ||
|
||
## Project Setup Command | ||
|
||
The project was created using the following command: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
# or | ||
bun dev | ||
pnpm create next-app@canary . --app --no-turbo --no-src-dir --no-eslint --import-alias @/* --tailwind | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
This command configures the project with: | ||
|
||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. | ||
- No turbo pack. | ||
- No `src` directory. | ||
- No ESLint (configured separately with [UpLeveled ESLint](https://github.com/upleveled/eslint-config-upleveled)). | ||
- Tailwind CSS for styling. | ||
- TypeScript support. | ||
- Import alias for simplified path imports (`@/`). | ||
|
||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. | ||
## Folder Structure | ||
|
||
## Learn More | ||
```plaintext | ||
. | ||
├── .vscode/ # VSCode settings and configurations | ||
├── app/ # Next.js app directory | ||
├── node_modules/ # Project dependencies | ||
├── public/ # Public assets | ||
├── .gitignore # Files to ignore in git | ||
├── eslint.config.js # ESLint configuration (UpLeveled) | ||
├── next-env.d.ts # TypeScript environment file | ||
├── next.config.ts # Next.js configuration | ||
├── package.json # Project dependencies and scripts | ||
├── pnpm-lock.yaml # Lockfile for pnpm dependencies | ||
├── postcss.config.mjs # PostCSS configuration | ||
├── prettier.config.js # Prettier configuration | ||
├── README.md # Project documentation | ||
├── stylelint.config.js # Stylelint configuration | ||
├── tailwind.config.ts # Tailwind CSS configuration | ||
├── tsconfig.json # TypeScript configuration | ||
``` | ||
|
||
## Linting and Formatting | ||
|
||
To learn more about Next.js, take a look at the following resources: | ||
The project uses the [UpLeveled ESLint config](https://github.com/upleveled/eslint-config-upleveled) for consistent code formatting and linting. You can run linting using the following command: | ||
|
||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
```bash | ||
pnpm lint | ||
``` | ||
|
||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! | ||
## Deployment | ||
|
||
## Deploy on Vercel | ||
The website is deployed using [Vercel](https://vercel.com/). You can find the production site at [jonaschlegel.com](https://jonaschlegel.com). | ||
|
||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
## License | ||
|
||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. | ||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import Script from 'next/script.js'; | ||
|
||
const googleAnalyticsTrackingId = 'G-6S9J34MPR3'; | ||
|
||
export default function Tracking() { | ||
return ( | ||
<> | ||
<Script | ||
id="_next-ga-init" | ||
dangerouslySetInnerHTML={{ | ||
__html: ` | ||
window.dataLayer = window.dataLayer || []; | ||
function gtag() { | ||
window.dataLayer.push(arguments); | ||
} | ||
gtag('consent', 'default', { | ||
ad_storage: 'denied', | ||
ad_user_data: 'denied', | ||
ad_personalization: 'denied', | ||
analytics_storage: 'denied', | ||
functionality_storage: 'denied', | ||
personalization_storage: 'denied', | ||
security_storage: 'granted', | ||
wait_for_update: 2000, | ||
}); | ||
gtag('set', 'ads_data_redaction', true); | ||
gtag('set', 'url_passthrough', true); | ||
gtag('js', new Date()); | ||
gtag('config', '${googleAnalyticsTrackingId}'); | ||
`, | ||
}} | ||
/> | ||
<Script | ||
id="_next-ga" | ||
src={`https://www.googletagmanager.com/gtag/js?id=${googleAnalyticsTrackingId}`} | ||
/> | ||
<Script | ||
id="fb-pixel" | ||
strategy="afterInteractive" | ||
dangerouslySetInnerHTML={{ | ||
__html: ` | ||
!function(f,b,e,v,n,t,s) { | ||
if(f.fbq) return; | ||
n = f.fbq = function() { | ||
n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments); | ||
}; | ||
if(!f._fbq) f._fbq = n; | ||
n.push = n; | ||
n.loaded = !0; | ||
n.version = '2.0'; | ||
n.queue = []; | ||
t = b.createElement(e); | ||
t.async = !0; | ||
t.src = v; | ||
s = b.getElementsByTagName(e)[0]; | ||
s.parentNode.insertBefore(t,s); | ||
}(window, document,'script', | ||
'https://connect.facebook.net/en_US/fbevents.js'); | ||
fbq('init', '812703364405783'); | ||
fbq('track', 'PageView'); | ||
`, | ||
}} | ||
/> | ||
<Script | ||
src="https://scripts.simpleanalyticscdn.com/latest.js" | ||
strategy="afterInteractive" | ||
defer | ||
/> | ||
<Script | ||
id="cookieyes" | ||
src="https://cdn-cookieyes.com/client_data/f49132772cc1d9f89dfe9534/script.js" | ||
/> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Image from 'next/image'; | ||
import type { FC } from 'react'; | ||
import { bannerData, jonaImage } from '../data/content'; | ||
import BannerText from './BannerText'; | ||
import ButtonSecondary from './ButtonSecondary'; | ||
|
||
const Banner: FC = () => { | ||
return ( | ||
<div className="mb-8 bg-yellow-100 py-3 text-neutral-950"> | ||
<div className="container mx-auto px-4"> | ||
<div className="flex flex-wrap items-center justify-between gap-4 lg:gap-8"> | ||
<div className="flex-1"> | ||
{bannerData.map((bannerText) => ( | ||
<BannerText key={`banner-${bannerText}`}>{bannerText}</BannerText> | ||
))} | ||
<div className="mt-4 text-center"> | ||
<ButtonSecondary | ||
className="bg-primary-accent font-semibold text-black border-none" | ||
pdfUrl="/data/Portfolio_JonaSchlegel.pdf" | ||
> | ||
Download my Portfolio | ||
</ButtonSecondary> | ||
</div> | ||
</div> | ||
<div className="shrink-0"> | ||
<div className="relative aspect-square size-32 overflow-hidden rounded-full lg:size-48"> | ||
<Image src={jonaImage} alt="jona" fill className="object-cover" /> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Banner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import type { FC, ReactNode } from 'react'; | ||
|
||
const BannerText: FC<{ children: ReactNode }> = ({ children }) => { | ||
return ( | ||
<p className="text-center font-merriweather text-xs tracking-tighter text-neutral-950 lg:text-xl"> | ||
{children} | ||
</p> | ||
); | ||
}; | ||
|
||
export default BannerText; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use client'; | ||
|
||
import type { Route } from 'next'; | ||
import Link from 'next/link'; | ||
import type { ButtonHTMLAttributes, FC } from 'react'; | ||
import React from 'react'; | ||
|
||
export interface ButtonProps { | ||
className?: string; | ||
translate?: string; | ||
sizeClass?: string; | ||
fontSize?: string; | ||
loading?: boolean; | ||
disabled?: boolean; | ||
type?: ButtonHTMLAttributes<HTMLButtonElement>['type']; | ||
href?: Route; | ||
onClick?: () => void; | ||
children?: React.ReactNode; | ||
} | ||
|
||
const Button: FC<ButtonProps> = ({ | ||
className = 'text-neutral-200 disabled:cursor-not-allowed', | ||
translate = '', | ||
sizeClass = 'py-3 px-4 mt-5 mb-5 sm:py-2 sm:px-6', | ||
fontSize = 'text-sm sm:text-base font-medium', | ||
disabled = false, | ||
href, | ||
children, | ||
type, | ||
loading, | ||
onClick = () => {}, | ||
}) => { | ||
const CLASSES = `relative inline-flex items-center justify-center rounded-full transition-colors ${fontSize} ${sizeClass} ${translate} ${className}`; | ||
|
||
const renderLoading = () => { | ||
return ( | ||
<svg | ||
className="-ml-1 mr-3 size-5 animate-spin" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
> | ||
<circle | ||
className="opacity-25" | ||
cx="12" | ||
cy="12" | ||
r="10" | ||
stroke="currentColor" | ||
strokeWidth="3" | ||
/> | ||
<path | ||
className="opacity-75" | ||
fill="currentColor" | ||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" | ||
/> | ||
</svg> | ||
); | ||
}; | ||
|
||
if (href) { | ||
return ( | ||
<Link href={href} className={CLASSES} onClick={onClick}> | ||
{children || `This is Link`} | ||
</Link> | ||
); | ||
} | ||
|
||
return ( | ||
<button | ||
disabled={disabled || loading} | ||
className={CLASSES} | ||
onClick={onClick} | ||
type={type} | ||
> | ||
{loading && renderLoading()} | ||
{children || `This is Button`} | ||
</button> | ||
); | ||
}; | ||
|
||
export default Button; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
'use client'; | ||
|
||
import React from 'react'; | ||
import type { ButtonProps } from './Button'; | ||
import Button from './Button'; | ||
|
||
declare global { | ||
interface Window { | ||
Calendly: { | ||
initPopupWidget: (options: { url: string }) => void; | ||
}; | ||
} | ||
} | ||
|
||
export interface ButtonPrimaryProps extends ButtonProps { | ||
email?: string; | ||
calendlyEventSlug?: string; | ||
} | ||
|
||
const ButtonPrimary: React.FC<ButtonPrimaryProps> = ({ | ||
className = '', | ||
email, | ||
calendlyEventSlug, | ||
...args | ||
}) => { | ||
const handleClick = () => { | ||
if (email) { | ||
window.location.href = `mailto:${email}`; | ||
} else if (calendlyEventSlug) { | ||
window.Calendly.initPopupWidget({ | ||
url: `https://calendly.com/${calendlyEventSlug}?primary_color=ff3367`, | ||
}); | ||
} | ||
}; | ||
|
||
return ( | ||
<Button | ||
className={`rounded-full bg-primary-accent font-semibold text-black ${className}`} | ||
{...args} | ||
onClick={handleClick} | ||
/> | ||
); | ||
}; | ||
|
||
export default ButtonPrimary; |
Oops, something went wrong.