Skip to content

Commit 2d90493

Browse files
committed
initial commit
0 parents  commit 2d90493

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2857
-0
lines changed

.github/workflows/playwright.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Playwright Tests
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-22.04
12+
timeout-minutes: 60
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: 20
20+
21+
- name: Install dependencies
22+
run: npm install
23+
24+
- name: Restore Playwright browsers cache
25+
id: pw-restore
26+
uses: actions/cache/restore@v4
27+
with:
28+
path: ~/.cache/ms-playwright
29+
key: ${{ runner.os }}-pw-1 # bump "1" when Playwright major changes
30+
restore-keys: |
31+
${{ runner.os }}-pw-
32+
33+
- name: Install Playwright browsers
34+
run: npx playwright install --with-deps
35+
36+
- name: Save Playwright browsers cache
37+
if: steps.pw-restore.outputs.cache-hit != 'true'
38+
uses: actions/cache/save@v4
39+
with:
40+
path: ~/.cache/ms-playwright
41+
key: ${{ steps.pw-restore.outputs.cache-primary-key }}
42+
43+
# ── Next.js build cache ─────────────────────────────────────────────
44+
- name: Restore Next.js build cache
45+
id: next-restore
46+
uses: actions/cache/restore@v4
47+
with:
48+
path: .next/cache
49+
key: ${{ runner.os }}-nextjs-${{ hashFiles('package-lock.json') }}
50+
restore-keys: |
51+
${{ runner.os }}-nextjs-
52+
53+
- name: Build Next.js app
54+
env:
55+
NODE_ENV: "production"
56+
run: npm run build
57+
58+
- name: Save Next.js build cache
59+
if: steps.next-restore.outputs.cache-hit != 'true'
60+
uses: actions/cache/save@v4
61+
with:
62+
path: .next/cache
63+
key: ${{ steps.next-restore.outputs.cache-primary-key }}
64+
65+
# ── Tests ───────────────────────────────────────────────────────────
66+
- name: Run Playwright tests
67+
run: npm run test
68+
env:
69+
NODE_ENV: "production"
70+
71+
# ── Upload HTML report (optional) ───────────────────────────────────
72+
- uses: actions/upload-artifact@v4
73+
if: ${{ !cancelled() }}
74+
with:
75+
name: playwright-report
76+
path: playwright-report/
77+
retention-days: 30

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# dependencies
2+
/node_modules
3+
/lucide-static
4+
/lucide-react
5+
6+
# package-lock.json
7+
package-lock.json
8+
9+
# testing
10+
/coverage
11+
/playwright-report
12+
13+
# next.js
14+
/.next/
15+
/out/
16+
.vercel
17+
dist/
18+
19+
# playwright
20+
/test-results
21+
22+
# production
23+
/build
24+
25+
# misc
26+
.DS_Store
27+
*.pem
28+
29+
# debug
30+
npm-debug.log*
31+
32+
# env files (can opt-in for committing if needed)
33+
.env*
34+
35+
# typescript
36+
*.tsbuildinfo
37+
next-env.d.ts
38+
39+
# VS Code
40+
# .vscode/
41+
# *.code-workspace
42+
.history/
43+

.husky/pre-commit

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# echo "🔍 Running Full Pre-Commit Checks..."
2+
3+
# # Run Prettier on all files
4+
# npx prettier --write . --ignore-unknown
5+
6+
# # Run ESLint on all JavaScript/TypeScript files
7+
# npx eslint --cache --fix . || exit 1
8+
9+
# # Re-stage all modified files so only one commit is needed
10+
# git add .
11+
12+
# # Type check the entire project (fails commit if there are errors)
13+
# npx tsc --noEmit || exit 1
14+
15+
# echo "✅ Pre-commit checks passed!"

.prettierignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules
2+
.next
3+
dist
4+
out
5+
.git
6+
.vscode
7+
.venv
8+
*.mdx
9+
.husky

.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": false,
3+
"singleQuote": false,
4+
"trailingComma": "es5",
5+
"plugins": ["prettier-plugin-tailwindcss"],
6+
"tabWidth": 2,
7+
"printWidth": 160
8+
}

.zero-ui/attributes.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* AUTO-GENERATED - DO NOT EDIT */
2+
export declare const bodyAttributes: {
3+
"data-mobile-menu": "closed" | "open";
4+
};

.zero-ui/attributes.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* AUTO-GENERATED - DO NOT EDIT */
2+
export const bodyAttributes = {
3+
"data-mobile-menu": "closed"
4+
};

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Next.js 15 Starter Repo with TypeScript, Tailwind v4, Framer Motion, and Playwright
2+
3+
## Setup
4+
5+
### 1. Initialize the Next.js Project
6+
7+
📂 next.js-starter/
8+
│── 📂 .vscode
9+
│ └── settings.json
10+
│── 📂 app
11+
│ │── 📂 privacy-policy
12+
│ │ │── PrivacyPolicy.tsx
13+
│ │ └── page.tsx
14+
│ │── 📂 terms-of-service
15+
│ │ │── Terms.tsx
16+
│ │ └── page.tsx
17+
│ │── 📂 contact
18+
│ │ └── page.tsx
19+
│ │── favicon.ico
20+
│ │── globals.css
21+
│ │── layout.tsx
22+
│ │── page.tsx
23+
│ │── robots.ts
24+
│ │── sitemap.ts
25+
│── 📂 config
26+
│ └── site.ts // Company information will be used in Metadata & Terms and Policy pages
27+
│── 📂 public
28+
│── .env
29+
│── .prettierignore
30+
│── .prettierrc
31+
│── README.md
32+
│── components.json
33+
│── eslint.config.mjs
34+
│── next.config.ts
35+
│── package-lock.json
36+
│── package.json
37+
│── postcss.config.mjs
38+
└── tsconfig.json
39+
40+
```
41+
42+
```

app/about/page.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Metadata } from "next"
2+
import { SITE_SLUGS } from "@/config/siteConfig"
3+
4+
export const metadata: Metadata = {
5+
title: "About",
6+
description: "About",
7+
alternates: {
8+
canonical: SITE_SLUGS.about,
9+
},
10+
}
11+
12+
const Page: React.FC = () => {
13+
return <div>About</div>
14+
}
15+
16+
export default Page

app/components/Footer.tsx

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import Link from "next/link"
2+
import { SITE_CONFIG, SITE_NAP, SITE_SLUGS } from "@/config/siteConfig"
3+
import { SocialLinks } from "./SocialLinks"
4+
5+
const year = new Date().getFullYear()
6+
7+
export const Footer: React.FC = () => {
8+
return (
9+
<footer className="bg-background-alt mt-10 overflow-hidden">
10+
<div className="p-10">
11+
{/* Main Footer Grid */}
12+
<div className="grid grid-cols-1 gap-12 pt-16 pb-8 md:pt-32 lg:grid-cols-3">
13+
{/* Navigation Links */}
14+
<div>
15+
<h3 className="after:bg-primary relative mb-4 after:absolute after:bottom-0 after:mt-2 after:block after:h-[3px] after:w-12">Navigate</h3>
16+
<nav className="flex flex-col gap-5">
17+
<Link href={SITE_SLUGS.home}>Home</Link>
18+
<Link href={SITE_SLUGS.contact}>Contact</Link>
19+
<Link href={SITE_SLUGS.services}>Services</Link>
20+
<Link rel="noopener noreferrer" target="_blank" href={SITE_NAP.googleReviewLink}>
21+
Write Review
22+
</Link>
23+
</nav>
24+
</div>
25+
26+
{/* Contact Info */}
27+
<div className="h-card">
28+
<h3 className="after:bg-primary relative mb-4 after:absolute after:bottom-0 after:mt-2 after:block after:h-[3px] after:w-16">Contact</h3>
29+
<div className="grid grid-cols-1 gap-4">
30+
<Link href={`tel:${SITE_NAP.phone}`} className="p-tel" aria-label={`Call ${SITE_CONFIG.title} in ${SITE_NAP.city} at ${SITE_NAP.formattedPhone}`}>
31+
{SITE_NAP.formattedPhone}
32+
</Link>
33+
<Link href={`mailto:${SITE_NAP.email}`} className="u-email" aria-label={`Email ${SITE_CONFIG.title} at ${SITE_NAP.email}`}>
34+
{SITE_NAP.email}
35+
</Link>
36+
<Link href={SITE_NAP.profiles.gbp} className="p-adr" target="_blank" rel="noopener noreferrer" aria-label="View our location on Google Maps">
37+
<span className="p-street-address">{SITE_NAP.address}</span>,<span className="p-locality"> {SITE_NAP.city}</span>,
38+
<span className="p-region"> {SITE_NAP.state}</span>,<span className="p-postal-code">{SITE_NAP.zipCode}</span>
39+
</Link>
40+
</div>
41+
</div>
42+
43+
{/* Business Hours Column */}
44+
<div>
45+
<h3 className="after:bg-primary relative mb-4 after:absolute after:bottom-0 after:mt-2 after:block after:h-[3px] after:w-16">Hours</h3>
46+
47+
<div className="flex flex-col gap-2">
48+
{SITE_NAP.openingHours.map(({ days, hours }) => (
49+
<p key={days}>
50+
<span className="text-nowrap">{days}: </span>
51+
<span className="text-nowrap">{hours}</span>
52+
</p>
53+
))}
54+
</div>
55+
</div>
56+
</div>
57+
<div className="mb-5 flex justify-center">
58+
<SocialLinks />
59+
</div>
60+
{/* Bottom Section */}
61+
<div className="flex flex-col items-center justify-between border-t border-neutral-600 pt-4 pb-4 lg:flex-row lg:items-end">
62+
<div className="flex w-fit flex-col items-center lg:items-start lg:justify-between">
63+
{/* Logo */}
64+
<div className="h-card flex w-fit items-center">
65+
{/* <Image src={Logo} alt={`{SITE_CONFIG.title} Kirkland Logo" width={50} height={50} className="u-logo`} /> */}
66+
<span className="p-name xs:text-[24px] text-xl font-extrabold text-nowrap uppercase italic">{SITE_CONFIG.title}</span>
67+
</div>
68+
69+
{/* Copyright */}
70+
<p className="mt-4 w-full text-center text-base! text-neutral-500 md:mt-0 lg:text-start">
71+
{year} Copyright © {SITE_CONFIG.title} | Website by
72+
<Link title="Seattle Web Design & SEO | Serbyte Development" href="https://www.serbyte.net/" className="text-primary font-medium hover:underline">
73+
{" "}
74+
Serbyte Development
75+
</Link>
76+
</p>
77+
</div>
78+
<div className="mt-4 flex w-fit items-center justify-center lg:mt-0">
79+
<Link
80+
title={`Terms of Service | ${SITE_CONFIG.title}`}
81+
href={`${SITE_CONFIG.url}/privacy-policy`}
82+
className="text-sm! text-nowrap text-neutral-500"
83+
>
84+
Privacy Policy{" "}
85+
</Link>
86+
<span className="mx-1 text-neutral-500">|</span>
87+
<Link
88+
title={`Privacy Policy | ${SITE_CONFIG.title}`}
89+
href={`${SITE_CONFIG.url}/terms-of-service`}
90+
className="text-sm! text-nowrap text-neutral-500"
91+
>
92+
Terms of Service
93+
</Link>
94+
</div>
95+
</div>
96+
</div>
97+
</footer>
98+
)
99+
}

0 commit comments

Comments
 (0)