Skip to content

Commit 8d9f31b

Browse files
Merge pull request #4 from nov-solutions/footer-styling-on-mobile-causes-width-overflow
fix width overflow issue by wrapping anchors in footer
2 parents 6433d7c + 7275451 commit 8d9f31b

File tree

6 files changed

+64
-50
lines changed

6 files changed

+64
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ node_modules
3535
next-env.d.ts
3636
**/sw.js
3737
**/workbox-*.js
38+
*.tsbuildinfo
3839

3940
# cdk
4041
cdk.out

.pre-commit-config.yaml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,34 @@ repos:
1616
rev: v3.1.0
1717
hooks:
1818
- id: prettier
19-
types: [file]
20-
files: '\.(js|jsx|ts|tsx|json|yaml|md|css|html)$'
19+
files: '^nextjs/.*\.(js|jsx|ts|tsx|json|yaml|md|css|html)$'
20+
args: [--write]
2121

22-
# eslint for nextjs
23-
- repo: local
22+
# typescript linter
23+
- repo: https://github.com/pre-commit/mirrors-eslint
24+
rev: v8.46.0
2425
hooks:
2526
- id: eslint
26-
name: eslint
27-
entry: bash -c 'cd nextjs && npm run lint'
27+
args: [--fix]
28+
29+
# typescript type checker
30+
- repo: local
31+
hooks:
32+
- id: tsc
33+
name: typescript type checker
34+
entry: npx --prefix nextjs tsc --noEmit --project nextjs/tsconfig.json
2835
language: system
29-
files: '\.(js|jsx|ts|tsx)$'
36+
files: '^nextjs/.*\.(ts|tsx)$'
3037
pass_filenames: false
3138

39+
# npm security audit
40+
- repo: local
41+
hooks:
42+
- id: npm-audit
43+
name: npm security audit
44+
entry: bash -c "cd nextjs && npm audit --audit-level=high"
45+
language: system
46+
3247
# python linter and formatter
3348
- repo: https://github.com/psf/black
3449
rev: 25.1.0

nextjs/.eslintrc.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": [
3+
"eslint:recommended",
4+
"plugin:@typescript-eslint/recommended",
5+
"plugin:@next/next/recommended"
6+
],
7+
"parser": "@typescript-eslint/parser",
8+
"ignorePatterns": ["node_modules/**", ".*", "**/*.config.js"]
9+
}

nextjs/eslint.config.mjs

Lines changed: 0 additions & 27 deletions
This file was deleted.

nextjs/src/components/marketing/footer.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ export default function Footer() {
1919

2020
return (
2121
<footer className="border-t">
22-
<div className="max-w-5xl mx-auto px-6 py-6">
23-
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
24-
<div className="flex items-center gap-6">
22+
<div className="max-w-5xl px-6 py-6 mx-auto">
23+
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
24+
<div className="flex flex-wrap items-center gap-6">
2525
<Link href="/" className="font-bold">
2626
{SITE_NAME}
2727
</Link>
28-
<nav className="flex items-center gap-4">
28+
<nav className="flex flex-wrap items-center gap-4">
2929
{links.map((link) => (
3030
<Link
3131
key={link.name}
3232
href={link.href}
33-
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
33+
className="text-sm transition-colors text-muted-foreground hover:text-foreground"
3434
>
3535
{link.name}
3636
</Link>
@@ -45,9 +45,9 @@ export default function Footer() {
4545
href={social.href}
4646
target="_blank"
4747
rel="noopener noreferrer"
48-
className="text-muted-foreground hover:text-foreground transition-colors"
48+
className="transition-colors text-muted-foreground hover:text-foreground"
4949
>
50-
<social.icon className="h-5 w-5" />
50+
<social.icon className="w-5 h-5" />
5151
</Link>
5252
))}
5353
<span className="text-sm text-muted-foreground">

setup_project.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import shutil
2020
import sys
2121
from pathlib import Path
22-
from typing import Optional
2322

2423
EXCLUDE_PATTERNS = (
2524
"setup_project.py",
@@ -64,7 +63,9 @@ def load_config() -> dict:
6463
return config
6564

6665

67-
def prompt(label: str, default: str = "", required: bool = False, secret: bool = False) -> str:
66+
def prompt(
67+
label: str, default: str = "", required: bool = False, secret: bool = False
68+
) -> str:
6869
"""Prompt user for input with optional default value."""
6970
if default:
7071
display = f"{label} [{default}]: "
@@ -74,6 +75,7 @@ def prompt(label: str, default: str = "", required: bool = False, secret: bool =
7475
while True:
7576
if secret:
7677
import getpass
78+
7779
value = getpass.getpass(display)
7880
else:
7981
value = input(display).strip()
@@ -111,7 +113,9 @@ def interactive_wizard() -> dict:
111113
prompt_section("Project Information")
112114
config["project"] = {
113115
"name": prompt("Project name (display name)", "My App", required=True),
114-
"name_slug": prompt("Project slug (lowercase, hyphens)", "my-app-web", required=True),
116+
"name_slug": prompt(
117+
"Project slug (lowercase, hyphens)", "my-app-web", required=True
118+
),
115119
}
116120

117121
# Branding
@@ -150,16 +154,22 @@ def interactive_wizard() -> dict:
150154
"account_id": prompt("AWS Account ID", "", required=True),
151155
"region": prompt("AWS Region", "us-west-2", required=True),
152156
"access_key_id": prompt("AWS Access Key ID (for backups)", ""),
153-
"secret_access_key": prompt("AWS Secret Access Key (for backups)", "", secret=True),
157+
"secret_access_key": prompt(
158+
"AWS Secret Access Key (for backups)", "", secret=True
159+
),
154160
}
155161

156162
# Database
157163
prompt_section("Database")
158164
config["database"] = {
159165
"name": prompt("Database name", "appdb", required=True),
160166
"user": prompt("Database user", "appuser", required=True),
161-
"password": prompt("Database password", "change_me_secure_password", required=True),
162-
"redis_password": prompt("Redis password", "change_me_redis_password", required=True),
167+
"password": prompt(
168+
"Database password", "change_me_secure_password", required=True
169+
),
170+
"redis_password": prompt(
171+
"Redis password", "change_me_redis_password", required=True
172+
),
163173
}
164174

165175
# Deployment
@@ -272,20 +282,26 @@ def build_replacements(config: dict) -> dict[str, str]:
272282
# Django
273283
"{{DJANGO_SECRET_KEY}}": generate_secret_key(),
274284
# Stripe
275-
"{{STRIPE_PUBLISHABLE_KEY}}": config.get("stripe", {}).get("publishable_key", ""),
285+
"{{STRIPE_PUBLISHABLE_KEY}}": config.get("stripe", {}).get(
286+
"publishable_key", ""
287+
),
276288
"{{STRIPE_SECRET_KEY}}": config.get("stripe", {}).get("secret_key", ""),
277289
"{{STRIPE_WEBHOOK_SECRET}}": config.get("stripe", {}).get("webhook_secret", ""),
278290
"{{STRIPE_PRO_PRICE_ID}}": config.get("stripe", {}).get("pro_price_id", ""),
279291
# Google OAuth
280292
"{{GOOGLE_CLIENT_ID}}": config.get("google_oauth", {}).get("client_id", ""),
281-
"{{GOOGLE_CLIENT_SECRET}}": config.get("google_oauth", {}).get("client_secret", ""),
293+
"{{GOOGLE_CLIENT_SECRET}}": config.get("google_oauth", {}).get(
294+
"client_secret", ""
295+
),
282296
# SendGrid
283297
"{{SENDGRID_API_KEY}}": config.get("sendgrid", {}).get("api_key", ""),
284298
# Sentry
285299
"{{SENTRY_DSN}}": config.get("sentry", {}).get("dsn", ""),
286300
# Backup
287301
"{{BACKUP_S3_BUCKET}}": config.get("backup", {}).get("s3_bucket", ""),
288-
"{{BACKUP_RETENTION_DAYS}}": config.get("backup", {}).get("retention_days", "30"),
302+
"{{BACKUP_RETENTION_DAYS}}": config.get("backup", {}).get(
303+
"retention_days", "30"
304+
),
289305
"{{BACKUP_PREFIX}}": config.get("backup", {}).get("prefix", "backups/"),
290306
}
291307

0 commit comments

Comments
 (0)