From 28f1a6f7b0c9697e5bb731056fcfca613c35b84d Mon Sep 17 00:00:00 2001 From: v0 Date: Wed, 11 Mar 2026 08:38:37 +0000 Subject: [PATCH] feat: create hackerspace management app landing page Add dark aesthetic, animated UI previews, icon-only design, clean copy, responsive layout, stats section, feature grid, clear CTAs Co-authored-by: Moheeb Zara <1184415+virgilvox@users.noreply.github.com> --- app/(landing)/layout.tsx | 14 ++ app/(landing)/page.tsx | 502 +++++++++++++++++++++++++++++++++++++++ app/page.tsx | 4 +- 3 files changed, 518 insertions(+), 2 deletions(-) create mode 100644 app/(landing)/layout.tsx create mode 100644 app/(landing)/page.tsx diff --git a/app/(landing)/layout.tsx b/app/(landing)/layout.tsx new file mode 100644 index 0000000..b76986f --- /dev/null +++ b/app/(landing)/layout.tsx @@ -0,0 +1,14 @@ +import type { Metadata } from 'next' + +export const metadata: Metadata = { + title: 'hackerspace.sh — Operational Software for Makerspaces', + description: 'Member management, dues tracking, task coordination, and project visibility. Built by people who have actually run these spaces.', +} + +export default function LandingLayout({ + children, +}: { + children: React.ReactNode +}) { + return children +} diff --git a/app/(landing)/page.tsx b/app/(landing)/page.tsx new file mode 100644 index 0000000..d3b4bac --- /dev/null +++ b/app/(landing)/page.tsx @@ -0,0 +1,502 @@ +'use client' + +import { useState, useEffect } from 'react' +import Link from 'next/link' + +// Icons +function IcoUsers({ className }: { className?: string }) { + return +} +function IcoTask({ className }: { className?: string }) { + return +} +function IcoFolder({ className }: { className?: string }) { + return +} +function IcoCreditCard({ className }: { className?: string }) { + return +} +function IcoKey({ className }: { className?: string }) { + return +} +function IcoChart({ className }: { className?: string }) { + return +} +function IcoArrow({ className }: { className?: string }) { + return +} +function IcoTerminal({ className }: { className?: string }) { + return +} + +// Mini UI Components with animations +function MiniMemberTable() { + const [activeRow, setActiveRow] = useState(0) + const members = [ + { name: 'Alex Chen', tier: 'PLUS', status: 'current' }, + { name: 'Jordan Mills', tier: 'BASIC', status: 'current' }, + { name: 'Sam Rivera', tier: 'PLUS', status: 'late' }, + { name: 'Casey Wong', tier: 'BASIC', status: 'current' }, + ] + + useEffect(() => { + const interval = setInterval(() => { + setActiveRow((prev) => (prev + 1) % members.length) + }, 2000) + return () => clearInterval(interval) + }, [members.length]) + + return ( +
+
+ Members + {members.length} +
+
+ {members.map((m, i) => ( +
+
+ {m.name.split(' ').map(n => n[0]).join('')} +
+ {m.name} + {m.tier} + +
+ ))} +
+
+ ) +} + +function MiniTaskList() { + const [checkedIndex, setCheckedIndex] = useState(-1) + const tasks = [ + { title: 'Clean laser cutter lens', area: 'Laser' }, + { title: 'Restock filament', area: '3D Printing' }, + { title: 'Update wiki docs', area: 'Admin' }, + ] + + useEffect(() => { + const interval = setInterval(() => { + setCheckedIndex((prev) => { + if (prev >= tasks.length - 1) return -1 + return prev + 1 + }) + }, 1500) + return () => clearInterval(interval) + }, [tasks.length]) + + return ( +
+
+ Tasks + + +
+
+ {tasks.map((t, i) => ( +
+
+ {i <= checkedIndex && ( + + + + )} +
+ + {t.title} + + {t.area} +
+ ))} +
+
+ ) +} + +function MiniProjectBoard() { + const [movingCard, setMovingCard] = useState(0) + + useEffect(() => { + const interval = setInterval(() => { + setMovingCard((prev) => (prev + 1) % 3) + }, 2500) + return () => clearInterval(interval) + }, []) + + const columns = ['BACKLOG', 'IN PROGRESS', 'DONE'] + + return ( +
+
+ Projects +
+
+ {columns.map((col, colIndex) => ( +
+
+ + {col} +
+ {colIndex === movingCard && ( +
+

CNC Upgrade

+
+
+
+
+ )} + {colIndex !== movingCard && colIndex === 1 && ( +
+

Placeholder

+
+ )} +
+ ))} +
+
+ ) +} + +function MiniPayments() { + const [linking, setLinking] = useState(false) + + useEffect(() => { + const interval = setInterval(() => { + setLinking((prev) => !prev) + }, 2000) + return () => clearInterval(interval) + }, []) + + return ( +
+
+ Payments + 2 unlinked +
+
+
+ PAYPAL + $50.00 + + {linking ? 'LINKED' : '+ LINK'} + +
+
+ VENMO + $75.00 + LINKED +
+
+
+ ) +} + +function MiniStats() { + const [count, setCount] = useState(47) + + useEffect(() => { + const interval = setInterval(() => { + setCount((prev) => prev + Math.floor(Math.random() * 3) - 1) + }, 3000) + return () => clearInterval(interval) + }, []) + + return ( +
+
+
+ + MEMBERS +
+

{count}

+
+
+
+ + TASKS +
+

12

+
+
+ ) +} + +export default function LandingPage() { + return ( +
+ {/* Nav */} + + + {/* Hero */} +
+
+
+
+

+ Operational Software for Makerspaces +

+

+ Run your hackerspace like the infrastructure it is +

+

+ Member management, dues tracking, task coordination, and project visibility. Built by people who have actually run these spaces. +

+
+ + Start Free + + + + See Features + +
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ + {/* Stats bar */} +
+
+
+ {[ + { label: 'Spaces running', value: '40+' }, + { label: 'Members managed', value: '2,800+' }, + { label: 'Tasks completed', value: '15k+' }, + { label: 'Payments tracked', value: '$380k+' }, + ].map((stat) => ( +
+

{stat.value}

+

{stat.label}

+
+ ))} +
+
+
+ + {/* Features */} +
+
+
+

Features

+

+ Everything your space needs, nothing it does not +

+

+ No bloated enterprise features. No learning curve. Just tools that match how hackerspaces actually operate. +

+
+ +
+ {[ + { + Icon: IcoUsers, + title: 'Member Directory', + description: 'Track membership tiers, payment status, access credentials, and contact info. Bulk actions for common operations.', + preview: , + }, + { + Icon: IcoTask, + title: 'Task Board', + description: 'Chores, maintenance, and one-off tasks with assignments, due dates, and recurring schedules. Claim and complete from anywhere.', + preview: , + }, + { + Icon: IcoFolder, + title: 'Project Tracking', + description: 'Kanban board for space projects. Track progress, assign areas, and keep the community informed about ongoing work.', + preview: , + }, + { + Icon: IcoCreditCard, + title: 'Payment Reconciliation', + description: 'Import from PayPal, Venmo, and Zeffy. Link transactions to members. Know exactly who owes what without spreadsheet hell.', + preview: , + }, + { + Icon: IcoKey, + title: 'Access Control', + description: 'Track key cards, door codes, and 24/7 access privileges. Integrated with member status so access stays current.', + preview: ( +
+
+ Access Logs +
+
+ {[ + { name: 'A. Chen', time: '2:34 PM', door: 'Main' }, + { name: 'J. Mills', time: '1:12 PM', door: 'Shop' }, + { name: 'S. Rivera', time: '11:45 AM', door: 'Main' }, + ].map((log) => ( +
+ + {log.name} + {log.door} + {log.time} +
+ ))} +
+
+ ), + }, + { + Icon: IcoChart, + title: 'Dashboard', + description: 'At a glance status on membership, open tasks, payment issues, and recent activity. Know what needs attention.', + preview: , + }, + ].map((feature) => ( +
+
+
+ +
+

{feature.title}

+
+

+ {feature.description} +

+
+ {feature.preview} +
+
+ ))} +
+
+
+ + {/* How it works */} +
+
+
+

How it works

+

+ From chaos to clarity in under an hour +

+
+ +
+ {[ + { + step: '01', + title: 'Import your members', + description: 'Paste from a spreadsheet or add them one by one. We handle the messy data.', + }, + { + step: '02', + title: 'Connect payments', + description: 'Link your PayPal or Zeffy account. Transactions import automatically.', + }, + { + step: '03', + title: 'Invite your board', + description: 'Add admins and treasurers. Everyone sees what they need to see.', + }, + ].map((item) => ( +
+

{item.step}

+

{item.title}

+

{item.description}

+
+ ))} +
+
+
+ + {/* Testimonial */} +
+
+
+ "We went from a shared Google Sheet that nobody updated to actually knowing who was current on dues. Game changer for our monthly board meetings." +
+
+

Marcus Webb

+

Treasurer, FreeGeek Chicago

+
+
+
+ + {/* CTA */} +
+
+

+ Your space deserves better than spreadsheets +

+

+ Free for spaces under 25 members. No credit card required. Set up in minutes. +

+
+ + Start Free + + + + Contact Us + +
+
+
+ + {/* Footer */} +
+
+
+
+ + hackerspace.sh +
+

+ Built for makerspaces, hackerspaces, and community workshops. +

+ +
+
+
+
+ ) +} diff --git a/app/page.tsx b/app/page.tsx index 54d0f5f..7f790fa 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,12 +1,12 @@ import { createClient } from '@/lib/supabase/server' import { redirect } from 'next/navigation' +import LandingPage from './(landing)/page' export default async function RootPage() { const supabase = await createClient() const { data: { user } } = await supabase.auth.getUser() if (user) { redirect('/dashboard') - } else { - redirect('/login') } + return }