Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjarling committed Feb 28, 2023
0 parents commit c20292f
Show file tree
Hide file tree
Showing 37 changed files with 7,896 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": ["next/core-web-vitals", "prettier"],
"plugins": ["simple-import-sort"],
"rules": {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error"
}
}
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# nextjs-typescript-tailwind-boilerplate

Baseline starter project which includes:

- Using Next13 `/app` directory and Server components by default
- Typescript
- TailwindCSS
- ESLint (auto import sorting) / Prettier
- Google Analytics (UA) example
- OpenGraph dynamic image setup using Next's `OG` package
- Masonry photo gallery w/ Lightbox support
- Hero component

## To start;

Clone the app and run `npm i`

Update the `package.json` file to the new site info
14 changes: 14 additions & 0 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Image from "next/image";

import casey from "@/public/images/IMG_0221.jpg";

const About = () => {
return (
<>
<Image src={casey} alt="Casey artwork" />
<section className="text-center section">Some text goes here</section>
</>
);
};

export default About;
20 changes: 20 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

html {
font-size: 21px;
}

@layer base {
h1,
h2,
h3,
h4,
h5 {
}

.section {
@apply max-w-3xl py-8 mx-auto;
}
}
41 changes: 41 additions & 0 deletions app/home-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import HeroImage from "@/components/Hero";

export default function Home() {
return (
<>
<main>
<HeroImage
headline="Headline goes here"
imageUrl="/student-artwork/IMG_0229(1).jpg"
altText="Hero"
/>

<section className="section">
<h2 className="text-xl bold">Educator</h2>
</section>

<div className="w-full h-36 bg-slate-400" />

<section className="section">
<h2 className="text-xl bold">Artist</h2>
</section>

<div className="w-full h-36 bg-slate-400" />

<section className="section">
<h2 className="text-xl bold">Observer</h2>
</section>

<div className="w-full h-36 bg-slate-400" />

<section className="section">
<h2 className="text-xl bold">Yogi</h2>
</section>

<div className="w-full h-36 bg-slate-400" />
</main>
</>
);
}
76 changes: 76 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import "./globals.css";

import { Metadata } from "next";
import { Montserrat } from "next/font/google";
import Script from "next/script";

import Nav from "@/components/Nav";

const montserrat = Montserrat({
subsets: ["latin"],
variable: "--font-montserrat",
});

export const metadata: Metadata = {
title: {
default: "Casey Murtaugh",
template: "%s | Casey Murtaugh",
},
description: "Artist and Educator",
openGraph: {
title: "Casey Murtaugh - Artist and Educator",
description: "Showcasing the ..",
url: "https://caseymurtaugh.art",
siteName: "Casey Murtaugh Art",
images: [
{
url: `${
process.env.NEXT_PUBLIC_BASE_URL
}/api/og?cover=${encodeURIComponent("/images/IMG_9823.jpg")}`,
},
],
locale: "en-US",
type: "website",
},
};

const links = [
{
href: "/about",
label: "About",
},
{
href: "/masonry-gallery",
label: "Masonry Gallery",
},
];

export default function RootLayout({
// Layouts must accept a children prop.
// This will be populated with nested layouts or pages
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className={montserrat.className}>
<body>
<Nav links={links} />
<>
{children}
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA}`}
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.NEXT_PUBLIC_GA}');
`}
</Script>
</>
</body>
</html>
);
}
28 changes: 28 additions & 0 deletions app/masonry-gallery/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { promises as fs } from "fs";
import path from "path";

import MasonryGallery, { MasonryImage } from "@/components/Masonry";
const sizeOf = require("image-size");

const GalleryPage = async () => {
const imageDirectory = path.join(process.cwd(), "/public/masonry-images");
const imageFilenames = await fs.readdir(imageDirectory);
const images = imageFilenames.map((ifn): MasonryImage => {
const dimensions = sizeOf(`${imageDirectory}/${ifn}`);
return {
filename: ifn,
...dimensions,
};
});

return (
<>
<section className="max-w-3xl py-8 mx-auto text-center">
Something goes here
</section>
<MasonryGallery dir="masonry-images" images={images} />
</>
);
};

export default GalleryPage;
31 changes: 31 additions & 0 deletions app/page.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.my-masonry-grid {
display: -webkit-box; /* Not needed if autoprefixing */
display: -ms-flexbox; /* Not needed if autoprefixing */
display: flex;
margin-left: -20px; /* gutter size offset */
width: auto;
}
.my-masonry-grid_column {
padding-left: 20px; /* gutter size */
background-clip: padding-box;
}

/* Style your items */
.my-masonry-grid_column > div {
/* change div to reference your elements you put in <Masonry> */
background: grey;
margin-bottom: 20px;
}

/* Optional, different gutter size on mobile */
@media (max-width: 800px) {
.my-masonry-grid {
margin-left: -15px; /* gutter size offset */
}
.my-masonry-grid_column {
padding-left: 15px; /* gutter size offset */
}
.my-masonry-grid_column > div {
margin-bottom: 15px; /* space between items */
}
}
11 changes: 11 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Metadata } from "next";

import HomePage from "./home-page";

export const metadata: Metadata = {
title: "Casey Murtaugh - Artist and Educator",
};

export default async function Page() {
return <HomePage />;
}
31 changes: 31 additions & 0 deletions components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Image from "next/image";

type HeroImageProps = {
headline: string;
imageUrl: string;
altText: string;
subHeadline?: string;
};

const HeroImage: React.FC<HeroImageProps> = ({
headline,
imageUrl,
altText,
subHeadline,
}) => {
return (
<div className="relative w-full h-screen overflow-hidden">
<Image src={imageUrl} alt={altText} fill className="z-0 object-cover" />
<div className="absolute z-10 text-center transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
<h1 className="mb-4 text-4xl font-bold text-white md:text-6xl">
{headline}
</h1>
{subHeadline && (
<p className="text-lg text-white md:text-xl">{subHeadline}</p>
)}
</div>
</div>
);
};

export default HeroImage;
Loading

0 comments on commit c20292f

Please sign in to comment.