Skip to content

Commit 302dec8

Browse files
committed
2 parents ae6ee41 + 11896f5 commit 302dec8

File tree

15 files changed

+619
-89
lines changed

15 files changed

+619
-89
lines changed

.github/workflows/format-check.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Prettier
2+
3+
on: [push]
4+
5+
jobs:
6+
prettier:
7+
runs-on: ubuntu-latest
8+
defaults:
9+
run:
10+
working-directory: junction-app
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- uses: oven-sh/setup-bun@v1
15+
with:
16+
bun-version: latest
17+
18+
- run: bun install
19+
20+
- name: Run Prettier check
21+
run: bun run format:check

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vercel

junction-app/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ yarn-error.log*
3939
# typescript
4040
*.tsbuildinfo
4141
next-env.d.ts
42+
43+
# DS_Store
44+
*.DS_Store

junction-app/app/auth/page.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useState } from "react";
3+
import { useEffect, useState } from "react";
44
import { useAuth } from "@/contexts/AuthContext";
55
import { useRouter } from "next/navigation";
66

@@ -13,9 +13,16 @@ export default function AuthPage() {
1313
const [error, setError] = useState("");
1414
const [loading, setLoading] = useState(false);
1515

16-
const { signIn, signUp, signInWithGoogle } = useAuth();
16+
const { user, signIn, signUp, signInWithGoogle } = useAuth();
1717
const router = useRouter();
1818

19+
// if logged in, redirect to dashboard
20+
useEffect(() => {
21+
if (user) {
22+
router.push("/dashboard");
23+
}
24+
}, [user, router]);
25+
1926
const handleSubmit = async (e: React.FormEvent) => {
2027
e.preventDefault();
2128
setError("");
@@ -28,8 +35,8 @@ export default function AuthPage() {
2835
await signUp(email, password, firstName, lastName);
2936
}
3037
router.push("/dashboard");
31-
} catch (err: any) {
32-
setError(err.message || "An error occurred");
38+
} catch (err: unknown) {
39+
setError(err instanceof Error ? err.message : "An error occurred");
3340
} finally {
3441
setLoading(false);
3542
}
@@ -42,8 +49,8 @@ export default function AuthPage() {
4249
try {
4350
await signInWithGoogle();
4451
router.push("/dashboard");
45-
} catch (err: any) {
46-
setError(err.message || "An error occurred");
52+
} catch (err: unknown) {
53+
setError(err instanceof Error ? err.message : "An error occurred");
4754
} finally {
4855
setLoading(false);
4956
}

junction-app/app/dashboard/page.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ export default function DashboardPage() {
5454
<div className="max-w-3xl mx-auto">
5555
<div className="bg-white shadow rounded-lg">
5656
<div className="px-4 py-5 sm:p-6">
57-
<h1 className="text-2xl font-bold text-gray-900 mb-6">
58-
Dashboard
59-
</h1>
57+
<h1 className="text-2xl font-bold text-gray-900 mb-6">Dashboard</h1>
6058

6159
<div className="space-y-4">
6260
<div>
@@ -80,10 +78,15 @@ export default function DashboardPage() {
8078
<p className="text-sm text-gray-600">
8179
<span className="font-medium">Member since:</span>{" "}
8280
{(() => {
83-
const dateValue = userData.createdAt instanceof Date
84-
? userData.createdAt
85-
: (userData.createdAt as { toDate?: () => Date }).toDate?.();
86-
return dateValue ? new Date(dateValue).toLocaleDateString() : '';
81+
const dateValue =
82+
userData.createdAt instanceof Date
83+
? userData.createdAt
84+
: (
85+
userData.createdAt as { toDate?: () => Date }
86+
).toDate?.();
87+
return dateValue
88+
? new Date(dateValue).toLocaleDateString()
89+
: "";
8790
})()}
8891
</p>
8992
)}

junction-app/app/layout.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Metadata } from "next";
22
import { Geist, Geist_Mono } from "next/font/google";
33
import "./globals.css";
44
import { AuthProvider } from "@/contexts/AuthContext";
5-
import Nav from "@/components/Nav";
5+
import { AppChrome } from "@/components/AppChrome";
66

77
const geistSans = Geist({
88
variable: "--font-geist-sans",
@@ -30,8 +30,7 @@ export default function RootLayout({
3030
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
3131
>
3232
<AuthProvider>
33-
<Nav />
34-
{children}
33+
<AppChrome>{children}</AppChrome>
3534
</AuthProvider>
3635
</body>
3736
</html>

junction-app/app/page.tsx

Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,15 @@
1-
import Link from "next/link";
1+
import { Demo } from "@/components/landing/Demo";
2+
import { Hero } from "@/components/landing/Hero";
3+
import { LandingFooter } from "@/components/landing/Footer";
4+
import { TrustScore } from "@/components/landing/TrustScore";
25

36
export default function Home() {
47
return (
5-
<div className="min-h-screen bg-gradient-to-b from-blue-50 to-white">
6-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20">
7-
<div className="text-center">
8-
<h1 className="text-5xl font-bold text-gray-900 mb-6">
9-
Welcome to Hackathon App
10-
</h1>
11-
<p className="text-xl text-gray-600 mb-8 max-w-2xl mx-auto">
12-
Build amazing things faster with our scaffold. Authentication, database, and UI components ready to go.
13-
</p>
14-
15-
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
16-
<Link
17-
href="/auth"
18-
className="bg-blue-600 text-white hover:bg-blue-700 px-8 py-3 rounded-lg text-lg font-medium transition-colors"
19-
>
20-
Get Started
21-
</Link>
22-
<Link
23-
href="/dashboard"
24-
className="border-2 border-blue-600 text-blue-600 hover:bg-blue-50 px-8 py-3 rounded-lg text-lg font-medium transition-colors"
25-
>
26-
View Dashboard
27-
</Link>
28-
</div>
29-
</div>
30-
31-
<div className="mt-20 grid grid-cols-1 md:grid-cols-3 gap-8">
32-
<div className="bg-white p-6 rounded-lg shadow-md">
33-
<h3 className="text-xl font-semibold text-gray-900 mb-3">
34-
Authentication Ready
35-
</h3>
36-
<p className="text-gray-600">
37-
Firebase authentication with email/password and Google sign-in out of the box.
38-
</p>
39-
</div>
40-
41-
<div className="bg-white p-6 rounded-lg shadow-md">
42-
<h3 className="text-xl font-semibold text-gray-900 mb-3">
43-
Database Integration
44-
</h3>
45-
<p className="text-gray-600">
46-
Firestore database configured and ready for your data models.
47-
</p>
48-
</div>
49-
50-
<div className="bg-white p-6 rounded-lg shadow-md">
51-
<h3 className="text-xl font-semibold text-gray-900 mb-3">
52-
Modern Stack
53-
</h3>
54-
<p className="text-gray-600">
55-
Built with Next.js 15, TypeScript, and Tailwind CSS for the best developer experience.
56-
</p>
57-
</div>
58-
</div>
59-
</div>
60-
</div>
8+
<main className="bg-zinc-950 text-white">
9+
<Hero />
10+
<Demo />
11+
<TrustScore />
12+
<LandingFooter />
13+
</main>
6114
);
6215
}

junction-app/bun.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
"name": "junction-app",
66
"dependencies": {
77
"firebase": "^12.6.0",
8+
"lucide-react": "^0.553.0",
89
"next": "16.0.3",
10+
"prettier": "^3.6.2",
911
"react": "19.2.0",
1012
"react-dom": "19.2.0",
1113
},
@@ -766,6 +768,8 @@
766768

767769
"lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
768770

771+
"lucide-react": ["[email protected]", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-BRgX5zrWmNy/lkVAe0dXBgd7XQdZ3HTf+Hwe3c9WK6dqgnj9h+hxV+MDncM88xDWlCq27+TKvHGE70ViODNILw=="],
772+
769773
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
770774

771775
"math-intrinsics": ["[email protected]", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
@@ -832,6 +836,8 @@
832836

833837
"prelude-ls": ["[email protected]", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
834838

839+
"prettier": ["[email protected]", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
840+
835841
"prop-types": ["[email protected]", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
836842

837843
"protobufjs": ["[email protected]", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client";
2+
3+
import { usePathname } from "next/navigation";
4+
import Nav from "@/components/Nav";
5+
6+
type AppChromeProps = {
7+
children: React.ReactNode;
8+
};
9+
10+
export function AppChrome({ children }: AppChromeProps) {
11+
const pathname = usePathname();
12+
const isLanding = pathname === "/";
13+
14+
const theme = isLanding ? "bg-zinc-950 text-white" : "bg-white text-zinc-900";
15+
16+
return (
17+
<div className={`${theme} min-h-screen`}>
18+
<Nav />
19+
{children}
20+
</div>
21+
);
22+
}

junction-app/components/Nav.tsx

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,84 @@
22

33
import Link from "next/link";
44
import { useAuth } from "@/contexts/AuthContext";
5+
import { usePathname } from "next/navigation";
6+
import { useEffect, useState } from "react";
57

68
export default function Nav() {
79
const { user } = useAuth();
10+
const pathname = usePathname();
11+
const isLanding = pathname === "/";
12+
const [scrolled, setScrolled] = useState(false);
13+
14+
useEffect(() => {
15+
if (!isLanding) return;
16+
17+
const handleScroll = () => {
18+
setScrolled(window.scrollY > 10);
19+
};
20+
21+
handleScroll();
22+
window.addEventListener("scroll", handleScroll);
23+
return () => window.removeEventListener("scroll", handleScroll);
24+
}, [isLanding]);
25+
26+
const navTheme = isLanding
27+
? scrolled
28+
? "border-white/10 bg-zinc-950/80 text-white shadow-lg shadow-black/30"
29+
: "border-transparent bg-transparent text-white"
30+
: "border-gray-200 bg-white text-gray-900 shadow-sm";
31+
const linkTheme = isLanding
32+
? "text-sm font-medium text-white/80 hover:text-white"
33+
: "text-sm font-medium text-gray-700 hover:text-gray-900";
34+
const buttonTheme = isLanding
35+
? "bg-white text-zinc-950 hover:bg-zinc-100"
36+
: "bg-blue-600 text-white hover:bg-blue-700";
37+
const secondaryLinkTheme = isLanding ? "text-white" : "text-gray-900";
38+
39+
const landingLinks = [
40+
{ href: "/#how-it-works", label: "How it works" },
41+
{ href: "/#features", label: "Features" },
42+
{ href: "/#demo", label: "Demo" },
43+
{ href: "/#trust-score", label: "Trust score" },
44+
];
845

946
return (
10-
<nav className="bg-white shadow-sm border-b">
47+
<nav className={`sticky top-0 z-50 border-b backdrop-blur ${navTheme}`}>
1148
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1249
<div className="flex justify-between items-center h-16">
13-
<div className="flex items-center">
14-
<Link href="/" className="text-xl font-bold text-gray-900">
15-
Hackathon App
50+
<div className="flex items-center gap-6">
51+
<Link
52+
href="/"
53+
className={`text-xl font-bold transition ${secondaryLinkTheme}`}
54+
>
55+
Aegis
1656
</Link>
57+
{isLanding && (
58+
<div className="hidden md:flex items-center gap-4">
59+
{landingLinks.map((link) => (
60+
<Link key={link.label} href={link.href} className={linkTheme}>
61+
{link.label}
62+
</Link>
63+
))}
64+
</div>
65+
)}
1766
</div>
1867

1968
<div className="flex items-center gap-4">
2069
{user ? (
2170
<>
2271
<Link
2372
href="/dashboard"
24-
className="text-gray-700 hover:text-gray-900 px-3 py-2 rounded-md text-sm font-medium"
73+
className={`${linkTheme} rounded-md px-3 py-2`}
2574
>
2675
Dashboard
2776
</Link>
28-
<span className="text-gray-600 text-sm">
29-
{user.email}
30-
</span>
3177
</>
3278
) : (
3379
<>
34-
<Link
35-
href="/"
36-
className="text-gray-700 hover:text-gray-900 px-3 py-2 rounded-md text-sm font-medium"
37-
>
38-
Home
39-
</Link>
4080
<Link
4181
href="/auth"
42-
className="bg-blue-600 text-white hover:bg-blue-700 px-4 py-2 rounded-md text-sm font-medium"
82+
className={`${buttonTheme} rounded-full px-4 py-2 text-sm font-medium transition`}
4383
>
4484
Sign In
4585
</Link>

0 commit comments

Comments
 (0)